reorganizing project structure and scripts
This commit is contained in:
parent
1c8b0df036
commit
26a5d9df4b
|
@ -3,6 +3,6 @@
|
|||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [v0.0.1-SNAPSHOT]
|
||||
## [v1.0.0-SNAPSHOT]
|
||||
|
||||
- First Release
|
|
@ -4,6 +4,7 @@
|
|||
# --build-arg="CONTAINER_INI=${CONTAINER_INI}" \
|
||||
# --build-arg="JAVA_VERSION=${JAVA_VERSION}" \
|
||||
# --build-arg="SMARTGEARS_VERSION=${SMARTGEARS_VERSION}" \
|
||||
# -f Dockerfile \
|
||||
# $PLATFORMS .
|
||||
|
||||
ARG JAVA_VERSION
|
||||
|
@ -11,7 +12,7 @@ ARG SMARTGEARS_VERSION
|
|||
|
||||
#FROM d4science/smartgears-distribution:${SMARTGEARS_VERSION}-java${JAVA_VERSION}-tomcat10.1.19
|
||||
FROM hub.dev.d4science.org/gcube/smartgears-distribution:${SMARTGEARS_VERSION}-java${JAVA_VERSION}-tomcat10.1.19
|
||||
ARG CONTAINER_INI="./docker/container.ini"
|
||||
ARG CONTAINER_INI="./dockerize/configuration/container.ini"
|
||||
ARG MVN_FINALNAME
|
||||
ARG MVN_NAME
|
||||
|
||||
|
@ -19,8 +20,8 @@ FROM hub.dev.d4science.org/gcube/smartgears-distribution:${SMARTGEARS_VERSION}-j
|
|||
RUN apt-get install unzip
|
||||
#FROM smartgears-distribution:${SMARTGEARS_VERSION}-java${JAVA_VERSION}-tomcat10.1.19
|
||||
|
||||
COPY ./docker/logback.xml /etc/
|
||||
COPY ./docker/*.gcubekey /tomcat/lib
|
||||
COPY ./dockerize/configuration/logback.xml /etc/
|
||||
COPY ./dockerize/configuration/*.gcubekey /tomcat/lib
|
||||
COPY ./target/${MVN_FINALNAME}.war /tmp
|
||||
RUN unzip /tmp/${MVN_FINALNAME}.war -d /tomcat/webapps/${MVN_NAME}
|
||||
COPY ${CONTAINER_INI} /etc/container.ini
|
||||
|
|
|
@ -4,17 +4,18 @@
|
|||
|
||||
start the docker container
|
||||
```sh
|
||||
./buildImageAndStart.sh -e
|
||||
|
||||
cd dockerize && ./buildImageAndStart.sh -e
|
||||
```
|
||||
|
||||
debug the docker container (read [### DEBUG] for details)
|
||||
```sh
|
||||
./buildImageAndStart.sh -d
|
||||
cd dockerize && ./buildImageAndStart.sh -d
|
||||
```
|
||||
|
||||
to compile and push to harbor registry with a custom container.ini file:
|
||||
```sh
|
||||
./buildImageAndStart.sh -r -m -l -c "./docker/container-XXX.ini"
|
||||
cd dockerize && ./buildImageAndStart.sh -r -m -l -c "./docker/container-XXX.ini"
|
||||
```
|
||||
|
||||
### Test URLs
|
||||
|
@ -42,7 +43,7 @@ curl -l 'http://localhost:8080/helloworld/gcube/resource/health'
|
|||
### Debug
|
||||
|
||||
start the docker container in debug Mode
|
||||
```./buildImageAndStartWithDebug.sh```
|
||||
```cd dockerize && ./buildImageAndStartWithDebug.sh -d```
|
||||
|
||||
connect the JAVA debugger to port 5005
|
||||
|
||||
|
@ -158,11 +159,11 @@ connect the JAVA debugger to port 5005
|
|||
* <scm> ???
|
||||
* <dependencyManagement> gcube dependency manager
|
||||
|
||||
* docker folder: folder with the configurations for the exevution of the application. are copied in the docker container during building
|
||||
* dockerize/configuration folder: folder with the configurations for the exevution of the application. are copied in the docker container during building
|
||||
|
||||
* docker/container.ini: configurations for the docker container.
|
||||
* dockerize/configuration/container.ini: configurations for the docker container.
|
||||
* create your own configuration copying an existing template
|
||||
* the default execution uses docker/docker/container.ini, it can be a simlink to a custom config
|
||||
* the default execution uses dockerize/configuration/container.ini, it can be a simlink to a custom config
|
||||
* gitignore ignores all container*.ini files in the folder excepting container.default.ini
|
||||
*
|
||||
* mode: [online/offline]: register the service on IS. use offline for local docker instances
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
# set -x # uncomment to debug script
|
||||
set -a
|
||||
. ./build_conf
|
||||
source ./build_conf
|
||||
set +a
|
||||
|
||||
ACCEPTED_JAVA_VERSIONs=(11 17)
|
||||
|
@ -119,11 +119,13 @@ while getopts $OPTSTRING opt; do
|
|||
done
|
||||
|
||||
if [ $COMPILE = true ]; then
|
||||
cd ..
|
||||
if [ $TEST = false ]; then
|
||||
mvn clean package -Dmaven.test.skip
|
||||
else
|
||||
mvn clean package
|
||||
fi
|
||||
cd -
|
||||
else
|
||||
echo "skipping mvn package"
|
||||
fi
|
||||
|
@ -137,13 +139,17 @@ if [ $MULTI_PLATFORM ]; then
|
|||
fi
|
||||
|
||||
echo "DOCKER_BUILD_NAME: $DOCKER_BUILD_NAME"
|
||||
cd ..
|
||||
docker build -t $DOCKER_BUILD_NAME \
|
||||
--build-arg="MVN_FINALNAME=$MVN_FINALNAME" \
|
||||
--build-arg="MVN_NAME=${MVN_NAME}" \
|
||||
--build-arg="CONTAINER_INI=${CONTAINER_INI}" \
|
||||
--build-arg="JAVA_VERSION=${JAVA_VERSION}" \
|
||||
--build-arg="SMARTGEARS_VERSION=${SMARTGEARS_VERSION}" \
|
||||
-f Dockerfile \
|
||||
$PLATFORMS .
|
||||
|
||||
cd -
|
||||
|
||||
if [ ${PUSH_DOCKER} = true ]; then
|
||||
docker tag $DOCKER_BUILD_NAME $DOCKER_IMAGE_NAME
|
|
@ -1,41 +1,55 @@
|
|||
MVN_VERSION=$(mvn -q \
|
||||
MVN_VERSION=$(cd .. && mvn -q \
|
||||
-Dexec.executable=echo \
|
||||
-Dexec.args='${project.version}' \
|
||||
--non-recursive \
|
||||
exec:exec)
|
||||
echo "MVN_VERSION: ${MVN_VERSION}"
|
||||
|
||||
|
||||
MVN_NAME=$(mvn -q \
|
||||
MVN_NAME=$(cd .. && mvn -q \
|
||||
-Dexec.executable=echo \
|
||||
-Dexec.args='${project.artifactId}' \
|
||||
--non-recursive \
|
||||
exec:exec)
|
||||
echo "MVN_NAME: ${MVN_NAME}"
|
||||
|
||||
MVN_FINALNAME=$(mvn -q \
|
||||
MVN_FINALNAME=$(cd .. && mvn -q \
|
||||
-Dexec.executable=echo \
|
||||
-Dexec.args='${project.build.finalName}' \
|
||||
--non-recursive \
|
||||
exec:exec)
|
||||
echo "MVN_FINALNAME: ${MVN_FINALNAME}"
|
||||
|
||||
JAVA_VERSION=$(mvn -q \
|
||||
JAVA_VERSION=$(cd .. && mvn -q \
|
||||
-Dexec.executable=echo \
|
||||
-Dexec.args='${maven.compiler.target}' \
|
||||
--non-recursive \
|
||||
exec:exec)
|
||||
echo "JAVA_VERSION: ${JAVA_VERSION}"
|
||||
|
||||
TOMCAT_VERSION=tomcat10.1.19
|
||||
SMARTGEARS_VERSION=$(mvn -q \
|
||||
echo "TOMCAT_VERSION: ${TOMCAT_VERSION}"
|
||||
|
||||
SMARTGEARS_VERSION=$(cd .. && mvn -q \
|
||||
-Dexec.executable=echo \
|
||||
-Dexec.args='${docker.smartgear.version}' \
|
||||
--non-recursive \
|
||||
exec:exec)
|
||||
echo "SMARTGEARS_VERSION: ${SMARTGEARS_VERSION}"
|
||||
|
||||
CONTAINER_INI="./docker/container.ini"
|
||||
CONTAINER_INI="./dockerize/configuration/container.ini"
|
||||
echo "CONTAINER_INI: ${CONTAINER_INI}"
|
||||
|
||||
IMAGE_VERSION=${MVN_VERSION}-java${JAVA_VERSION}-smartgears${SMARTGEARS_VERSION}
|
||||
echo "IMAGE_VERSION: ${IMAGE_VERSION}"
|
||||
|
||||
DOCKER_BUILD_NAME=$MVN_NAME:$IMAGE_VERSION
|
||||
echo "DOCKER_BUILD_NAME: ${DOCKER_BUILD_NAME}"
|
||||
|
||||
SMARTGEAR_IMAGE=hub.dev.d4science.org/gcube/smartgears-distribution:${SMARTGEARS_VERSION}-java${JAVA_VERSION}-${TOMCAT_VERSION}
|
||||
echo "SMARTGEAR_IMAGE: ${SMARTGEAR_IMAGE}"
|
||||
|
||||
DOCKER_IMAGE_NAME=d4science/$DOCKER_BUILD_NAME
|
||||
echo "DOCKER_IMAGE_NAME: ${DOCKER_IMAGE_NAME}"
|
||||
|
||||
HARBOR_IMAGE_NAME=hub.dev.d4science.org/gcube/$DOCKER_BUILD_NAME
|
||||
echo "HARBOR_IMAGE_NAME: ${HARBOR_IMAGE_NAME}"
|
|
@ -4,8 +4,8 @@
|
|||
xsi:noNamespaceSchemaLocation="http://enunciate.webcohesion.com/schemas/enunciate-2.14.0.xsd">
|
||||
<description package="org.gcube.service.idm" />
|
||||
<api-classes>
|
||||
<include pattern="org.gcube.service.helloword.rest.*" />
|
||||
<exclude pattern="org.gcube.service.helloword.*" />
|
||||
<include pattern="org.gcube.service.helloworld.rest.*" />
|
||||
<exclude pattern="org.gcube.service.helloworld.*" />
|
||||
</api-classes>
|
||||
<modules>
|
||||
<gwt-json-overlay disabled="true" />
|
|
@ -16,7 +16,7 @@ import os
|
|||
|
||||
|
||||
def getVersion():
|
||||
cmd = """cd .. && \
|
||||
cmd = """cd ../.. && \
|
||||
mvn -q \
|
||||
-Dexec.executable=echo \
|
||||
-Dexec.args='${project.version}' \
|
||||
|
@ -27,9 +27,9 @@ def getVersion():
|
|||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = 'gCube Catalogue (gCat) Service'
|
||||
copyright = '2022, Luca Frosini (ISTI-CNR)'
|
||||
author = 'Luca Frosini (ISTI-CNR)'
|
||||
project = 'gCube Hello World Service SG4'
|
||||
copyright = '2024, gCube System'
|
||||
author = 'Luca Frosini (ISTI-CNR), Lucio Lelii (ISTI-CNR), Alfredo Oliviero (ISTI-CNR)'
|
||||
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = getVersion()
|
|
@ -7,3 +7,4 @@ excludes:
|
|||
- path: /guest
|
||||
- path: /guest/*
|
||||
- path: /api-docs/*
|
||||
- path: /docs/*
|
||||
|
|
193
pom.xml
193
pom.xml
|
@ -2,19 +2,81 @@
|
|||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.gcube.service</groupId>
|
||||
<artifactId>helloworld</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>Smartgears HelloWorld Service</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
|
||||
<parent>
|
||||
<groupId>org.gcube.tools</groupId>
|
||||
<artifactId>maven-parent</artifactId>
|
||||
<version>1.2.0</version>
|
||||
</parent>
|
||||
|
||||
|
||||
<groupId>org.gcube.service</groupId>
|
||||
<artifactId>helloworld</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<name>Smartgears 4 HelloWorld Service</name>
|
||||
<description>
|
||||
|
||||
</description>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<organization>
|
||||
<name>gCube System</name>
|
||||
<url>https://www.gcube-system.org/</url>
|
||||
</organization>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>luca.frosini</id>
|
||||
<name>Luca Frosini</name>
|
||||
<email>luca.frosini@isti.cnr.it</email>
|
||||
<url>https://www.isti.cnr.it/en/about/people-detail/141/Frosini_Luca</url>
|
||||
<organization>ISTI-CNR</organization>
|
||||
<organizationUrl>https://www.isti.cnr.it/</organizationUrl>
|
||||
<roles>
|
||||
<role>researcher</role>
|
||||
<role>developer</role>
|
||||
</roles>
|
||||
<timezone>Europe/Rome</timezone>
|
||||
<properties>
|
||||
<picUrl>https://gravatar.com/lucafrosini</picUrl>
|
||||
</properties>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>lucio.lelii</id>
|
||||
<name>Lucio Lelii</name>
|
||||
<email>lucio.lelii@isti.cnr.it</email>
|
||||
<url></url>
|
||||
<organization>ISTI-CNR</organization>
|
||||
<organizationUrl>https://www.isti.cnr.it/en/about/people-detail/184/Lelii_Lucio/</organizationUrl>
|
||||
<roles>
|
||||
<role>researcher</role>
|
||||
<role>developer</role>
|
||||
</roles>
|
||||
<timezone>Europe/Rome</timezone>
|
||||
<properties>
|
||||
<picUrl>https://gravatar.com/latinswing</picUrl>
|
||||
</properties>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>alfredo.oliviero</id>
|
||||
<name>Alfredo Oliviero</name>
|
||||
<email>alfredo.oliviero@isti.cnr.it</email>
|
||||
<url></url>
|
||||
<organization>ISTI-CNR</organization>
|
||||
<organizationUrl>https://www.isti.cnr.it/en/about/people-detail/1087/Oliviero_Alfredo/</organizationUrl>
|
||||
<roles>
|
||||
<role>researcher</role>
|
||||
<role>developer</role>
|
||||
</roles>
|
||||
<timezone>Europe/Rome</timezone>
|
||||
<properties>
|
||||
<picUrl>https://gravatar.com/alfredooliviero</picUrl>
|
||||
</properties>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
|
||||
|
||||
<properties>
|
||||
<java.version>11</java.version>
|
||||
|
||||
|
@ -24,15 +86,17 @@
|
|||
|
||||
<!-- OPTIONAL. for authorization-control-library -->
|
||||
<aspectj-plugin.version>1.14.0</aspectj-plugin.version>
|
||||
|
||||
|
||||
<enunciate.version>2.16.1</enunciate.version>
|
||||
|
||||
|
||||
<docker.smartgear.version>4.0.1-SNAPSHOT</docker.smartgear.version>
|
||||
</properties>
|
||||
|
||||
<scm>
|
||||
<connection>scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git</connection>
|
||||
<developerConnection>scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git</developerConnection>
|
||||
<connection>
|
||||
scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git</connection>
|
||||
<developerConnection>
|
||||
scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git</developerConnection>
|
||||
<url>https://code-repo.d4science.org/gCubeSystem/${project.artifactId}</url>
|
||||
</scm>
|
||||
|
||||
|
@ -119,29 +183,29 @@
|
|||
<!-- OPTIONAL. authorization-control-library: add this plugin if you
|
||||
want to use gcube
|
||||
authorization control funzionalities -->
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.codehaus.mojo</groupId>-->
|
||||
<!-- <artifactId>aspectj-maven-plugin</artifactId>-->
|
||||
<!-- <version>${aspectj-plugin.version}</version>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <complianceLevel>${java.version}</complianceLevel>-->
|
||||
<!-- <source>${java.version}</source>-->
|
||||
<!-- <target>${java.version}</target>-->
|
||||
<!-- <aspectLibraries>-->
|
||||
<!-- <aspectLibrary>-->
|
||||
<!-- <groupId>org.gcube.common</groupId>-->
|
||||
<!-- <artifactId>authorization-control-library</artifactId>-->
|
||||
<!-- </aspectLibrary>-->
|
||||
<!-- </aspectLibraries>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- <executions>-->
|
||||
<!-- <execution>-->
|
||||
<!-- <goals>-->
|
||||
<!-- <goal>compile</goal>-->
|
||||
<!-- </goals>-->
|
||||
<!-- </execution>-->
|
||||
<!-- </executions>-->
|
||||
<!-- </plugin>-->
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.codehaus.mojo</groupId>-->
|
||||
<!-- <artifactId>aspectj-maven-plugin</artifactId>-->
|
||||
<!-- <version>${aspectj-plugin.version}</version>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <complianceLevel>${java.version}</complianceLevel>-->
|
||||
<!-- <source>${java.version}</source>-->
|
||||
<!-- <target>${java.version}</target>-->
|
||||
<!-- <aspectLibraries>-->
|
||||
<!-- <aspectLibrary>-->
|
||||
<!-- <groupId>org.gcube.common</groupId>-->
|
||||
<!-- <artifactId>authorization-control-library</artifactId>-->
|
||||
<!-- </aspectLibrary>-->
|
||||
<!-- </aspectLibraries>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- <executions>-->
|
||||
<!-- <execution>-->
|
||||
<!-- <goals>-->
|
||||
<!-- <goal>compile</goal>-->
|
||||
<!-- </goals>-->
|
||||
<!-- </execution>-->
|
||||
<!-- </executions>-->
|
||||
<!-- </plugin>-->
|
||||
|
||||
|
||||
<!-- Sphinx plugin' -->
|
||||
|
@ -150,12 +214,14 @@
|
|||
<artifactId>sphinx-maven-plugin</artifactId>
|
||||
<version>2.10.0</version>
|
||||
<configuration>
|
||||
<outputDirectory>${project.build.directory}/${project.build.finalName}/docs</outputDirectory>
|
||||
<outputDirectory>
|
||||
${project.build.directory}${file.separator}${project.build.finalName}${file.separator}docs</outputDirectory>
|
||||
<builder>html</builder>
|
||||
<configDirectory>${basedir}/sphinx</configDirectory>
|
||||
<sourceDirectory>${basedir}/sphinx</sourceDirectory>
|
||||
<configDirectory>${project.basedir}${file.separator}documentation${file.separator}sphinx</configDirectory>
|
||||
<sourceDirectory>${project.basedir}${file.separator}documentation${file.separator}sphinx</sourceDirectory>
|
||||
<!-- brew install sphinx-doc -->
|
||||
<binaryUrl>file:/opt/homebrew/opt/sphinx-doc/bin/sphinx-build</binaryUrl>
|
||||
<binaryUrl>
|
||||
file:/opt/homebrew/opt/sphinx-doc/bin/sphinx-build</binaryUrl>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
|
@ -180,34 +246,35 @@
|
|||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<!-- <docsDir>${project.build.directory}${file.separator}${project.artifactId}-${project.version}${file.separator}api-docs</docsDir>-->
|
||||
<configFile>${project.basedir}${file.separator}documentation${file.separator}enunciate.xml</configFile>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- Copy Enunciate Documentation from your-application/api-docs
|
||||
into your war -->
|
||||
<!-- Copy Enunciate Documentation from your-application/api-docs into your war -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-enunciate-docs</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>target</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<targetPath>
|
||||
${project.build.directory}/${project.artifactId}-${project.version}/api-docs</targetPath>
|
||||
<directory>
|
||||
${project.build.directory}/api-docs</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-enunciate-docs</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>target</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<targetPath>${project.build.directory}${file.separator}${project.artifactId}-${project.version}${file.separator}api-docs</targetPath>
|
||||
<directory>${project.build.directory}/api-docs</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
|
|
|
@ -14,11 +14,19 @@
|
|||
<param-name>jersey.config.server.provider.packages</param-name>
|
||||
<param-value>org.gcube.service.helloworld.rest</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>jersey.config.server.provider.packages</param-name>
|
||||
<param-value>org.gcube.service.helloworld.mappers</param-value>
|
||||
</init-param>
|
||||
<!-- <init-param>-->
|
||||
<!-- <param-name>jersey.config.server.provider.packages</param-name>-->
|
||||
<!-- <param-value>org.gcube.service.helloworld.mappers</param-value>-->
|
||||
<!-- </init-param>-->
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>default</servlet-name>
|
||||
<url-pattern>/docs/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
<servlet-mapping>
|
||||
<servlet-name>default</servlet-name>
|
||||
<url-pattern>/api-docs/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
<servlet-mapping>
|
||||
<servlet-name>helloword</servlet-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
|
|
Loading…
Reference in New Issue