├── .github
└── workflows
│ └── gradle.yml
├── .gitignore
├── Dockerfile
├── LICENSE
├── README.md
├── bin
├── .gitignore
├── start_ServiceAgentGenerator.bat
├── start_ServiceAgentGenerator.sh
├── start_UserAgentGenerator.bat
└── start_UserAgentGenerator.sh
├── docker-entrypoint.sh
├── etc
├── i5.las2peer.connectors.webConnector.WebConnector.properties
├── i5.las2peer.services.servicePackage.TemplateService.properties
└── nodeInfo.xml
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── template_project
├── build.gradle
└── src
├── main
└── java
│ └── i5
│ └── las2peer
│ └── services
│ └── templateService
│ └── TemplateService.java
└── test
└── java
└── i5
└── las2peer
└── services
└── templateService
└── ServiceTest.java
/.github/workflows/gradle.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build a Java project with Gradle
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
3 |
4 | name: Java CI with Gradle
5 |
6 | # Triggers the workflow on push or pull request events (on every branch)
7 | on:
8 | push:
9 | branches: [ master, develop]
10 | jobs:
11 | build:
12 |
13 | runs-on: ubuntu-latest
14 |
15 | steps:
16 | - uses: actions/checkout@v2
17 | - name: Set up JDK 17
18 | uses: actions/setup-java@v1
19 | with:
20 | java-version: 17
21 | - name: Grant execute permission for gradlew
22 | run: chmod +x gradlew
23 | - name: Build with Gradle
24 | run: ./gradlew build
25 | - uses: codecov/codecov-action@v1
26 | with:
27 | files: ./template_project/export/jacoco/test/jacocoTestReport.xml
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /template_project/output/
2 | /template_project/export/
3 | /node-storage/
4 | /.las2peer/
5 | /tmp/
6 | /log/
7 | /template_project/log/
8 | /lib/
9 | /etc/ivy/ivy.jar
10 | /service/
11 | /out/
12 | /.idea/
13 | *.iml
14 | .DS_Store
15 | /.settings/
16 | /junitvmwatcher*.properties
17 | /junit*.properties
18 | /etc/startup/
19 | *.secret
20 | archiva_credentials.xml
21 | .classpath
22 | .project
23 | .settings
24 |
25 | # Ignore Gradle project-specific cache directory
26 | .gradle
27 |
28 | # Ignore Gradle build output directory
29 | build
30 | .vscode
31 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM openjdk:17-jdk-alpine
2 |
3 | ENV HTTP_PORT=8080
4 | ENV HTTPS_PORT=8443
5 | ENV LAS2PEER_PORT=9011
6 |
7 | RUN apk add --update bash tzdata curl && rm -f /var/cache/apk/*
8 | RUN addgroup -g 1000 -S las2peer && \
9 | adduser -u 1000 -S las2peer -G las2peer
10 |
11 | COPY --chown=las2peer:las2peer . /src
12 | WORKDIR /src
13 |
14 | # run the rest as unprivileged user
15 | USER las2peer
16 | # Include this in case you build on a windows machine
17 | #RUN dos2unix gradlew
18 | #RUN dos2unix gradle.properties
19 | #RUN dos2unix /src/docker-entrypoint.sh
20 | #RUN dos2unix /src/etc/i5.las2peer.connectors.webConnector.WebConnector.properties
21 | #RUN dos2unix /src/etc/i5.las2peer.services.servicePackage.TemplateService.properties
22 | RUN chmod -R a+rwx /src
23 | RUN chmod +x /src/docker-entrypoint.sh
24 | RUN chmod +x gradlew && ./gradlew build
25 |
26 |
27 |
28 |
29 | EXPOSE $HTTP_PORT
30 | EXPOSE $HTTPS_PORT
31 | EXPOSE $LAS2PEER_PORT
32 | RUN chmod +x /src/docker-entrypoint.sh
33 | ENTRYPOINT ["/src/docker-entrypoint.sh"]
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | CC0 1.0 Universal
2 |
3 | Statement of Purpose
4 |
5 | The laws of most jurisdictions throughout the world automatically confer
6 | exclusive Copyright and Related Rights (defined below) upon the creator and
7 | subsequent owner(s) (each and all, an "owner") of an original work of
8 | authorship and/or a database (each, a "Work").
9 |
10 | Certain owners wish to permanently relinquish those rights to a Work for the
11 | purpose of contributing to a commons of creative, cultural and scientific
12 | works ("Commons") that the public can reliably and without fear of later
13 | claims of infringement build upon, modify, incorporate in other works, reuse
14 | and redistribute as freely as possible in any form whatsoever and for any
15 | purposes, including without limitation commercial purposes. These owners may
16 | contribute to the Commons to promote the ideal of a free culture and the
17 | further production of creative, cultural and scientific works, or to gain
18 | reputation or greater distribution for their Work in part through the use and
19 | efforts of others.
20 |
21 | For these and/or other purposes and motivations, and without any expectation
22 | of additional consideration or compensation, the person associating CC0 with a
23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
25 | and publicly distribute the Work under its terms, with knowledge of his or her
26 | Copyright and Related Rights in the Work and the meaning and intended legal
27 | effect of CC0 on those rights.
28 |
29 | 1. Copyright and Related Rights. A Work made available under CC0 may be
30 | protected by copyright and related or neighboring rights ("Copyright and
31 | Related Rights"). Copyright and Related Rights include, but are not limited
32 | to, the following:
33 |
34 | i. the right to reproduce, adapt, distribute, perform, display, communicate,
35 | and translate a Work;
36 |
37 | ii. moral rights retained by the original author(s) and/or performer(s);
38 |
39 | iii. publicity and privacy rights pertaining to a person's image or likeness
40 | depicted in a Work;
41 |
42 | iv. rights protecting against unfair competition in regards to a Work,
43 | subject to the limitations in paragraph 4(a), below;
44 |
45 | v. rights protecting the extraction, dissemination, use and reuse of data in
46 | a Work;
47 |
48 | vi. database rights (such as those arising under Directive 96/9/EC of the
49 | European Parliament and of the Council of 11 March 1996 on the legal
50 | protection of databases, and under any national implementation thereof,
51 | including any amended or successor version of such directive); and
52 |
53 | vii. other similar, equivalent or corresponding rights throughout the world
54 | based on applicable law or treaty, and any national implementations thereof.
55 |
56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of,
57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
59 | and Related Rights and associated claims and causes of action, whether now
60 | known or unknown (including existing as well as future claims and causes of
61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum
62 | duration provided by applicable law or treaty (including future time
63 | extensions), (iii) in any current or future medium and for any number of
64 | copies, and (iv) for any purpose whatsoever, including without limitation
65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
66 | the Waiver for the benefit of each member of the public at large and to the
67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver
68 | shall not be subject to revocation, rescission, cancellation, termination, or
69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work
70 | by the public as contemplated by Affirmer's express Statement of Purpose.
71 |
72 | 3. Public License Fallback. Should any part of the Waiver for any reason be
73 | judged legally invalid or ineffective under applicable law, then the Waiver
74 | shall be preserved to the maximum extent permitted taking into account
75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
76 | is so judged Affirmer hereby grants to each affected person a royalty-free,
77 | non transferable, non sublicensable, non exclusive, irrevocable and
78 | unconditional license to exercise Affirmer's Copyright and Related Rights in
79 | the Work (i) in all territories worldwide, (ii) for the maximum duration
80 | provided by applicable law or treaty (including future time extensions), (iii)
81 | in any current or future medium and for any number of copies, and (iv) for any
82 | purpose whatsoever, including without limitation commercial, advertising or
83 | promotional purposes (the "License"). The License shall be deemed effective as
84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the
85 | License for any reason be judged legally invalid or ineffective under
86 | applicable law, such partial invalidity or ineffectiveness shall not
87 | invalidate the remainder of the License, and in such case Affirmer hereby
88 | affirms that he or she will not (i) exercise any of his or her remaining
89 | Copyright and Related Rights in the Work or (ii) assert any associated claims
90 | and causes of action with respect to the Work, in either case contrary to
91 | Affirmer's express Statement of Purpose.
92 |
93 | 4. Limitations and Disclaimers.
94 |
95 | a. No trademark or patent rights held by Affirmer are waived, abandoned,
96 | surrendered, licensed or otherwise affected by this document.
97 |
98 | b. Affirmer offers the Work as-is and makes no representations or warranties
99 | of any kind concerning the Work, express, implied, statutory or otherwise,
100 | including without limitation warranties of title, merchantability, fitness
101 | for a particular purpose, non infringement, or the absence of latent or
102 | other defects, accuracy, or the present or absence of errors, whether or not
103 | discoverable, all to the greatest extent permissible under applicable law.
104 |
105 | c. Affirmer disclaims responsibility for clearing rights of other persons
106 | that may apply to the Work or any use thereof, including without limitation
107 | any person's Copyright and Related Rights in the Work. Further, Affirmer
108 | disclaims responsibility for obtaining any necessary consents, permissions
109 | or other rights required for any use of the Work.
110 |
111 | d. Affirmer understands and acknowledges that Creative Commons is not a
112 | party to this document and has no duty or obligation with respect to this
113 | CC0 or use of the Work.
114 |
115 | For more information, please see
116 |
117 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | las2peer-Template-Project
5 |
6 | 
7 | [](https://codecov.io/gh/rwth-acis/las2peer-template-project)
8 | [](https://libraries.io/github/rwth-acis/las2peer-template-project)
9 |
10 | This project can be used as a starting point for your las2peer service development.
11 | It contains everything needed to start las2peer service development, you do not need to add any dependencies manually.
12 |
13 | For documentation on the las2peer service API, please refer to the [wiki](https://github.com/rwth-acis/las2peer-Template-Project/wiki).
14 |
15 | Please follow the instructions of this ReadMe to setup your basic service development environment.
16 |
17 | ## Preparations
18 |
19 | ### Java
20 |
21 | las2peer template uses **Java 14**.
22 | las2peer uses **Java 17**.
23 |
24 | ## Quick Setup of your Service Development Environment
25 |
26 | *If you never used las2peer before, it is recommended that you first visit the
27 | [Step by Step - First Service](https://github.com/rwth-acis/las2peer-Template-Project/wiki/Step-By-Step:-First-Service)
28 | tutorial for a more detailed guidance on how to use this template.*
29 |
30 | Follow these four steps to setup your project:
31 | 1. If you use Eclipse (for our guides we are using version 2020-12), import this project (as Gradle -> Existing Gradle Project). Please make sure, that Java 17 is available in Eclipse. During the import process, the .classpath files will be generated automatically.
32 | 2. The service source code can be found at `i5.las2peer.services.templateService.TemplateService`.
33 | (Optional: Change [gradle.properties](gradle.properties)
34 | according to the service you want to build. Rename your build directory structure according to the names you gave.)
35 | 3. Compile your service with `./gradlew clean jar`. This will also build the service jar.
36 | 4. Generate documentation, run your JUnit tests and generate service and user agent with `./gradlew clean build` (If this did not run check that the policy files are working correctly).
37 |
38 | The jar file with your service will be in "template_project/export/" and "service/" and the generated agent XML files in "etc/startup/".
39 | You can find the JUnit reports in the folder "template_project/build/reports/tests/".
40 |
41 | If you decide to change the dependencies of your project, please make sure to refresh the Gradle project in Eclipse by right-clicking on your project and then choosing Gradle -> Refresh Gradle Project.
42 | Also run "gradle cleanAll" to remove all previously added libraries.
43 |
44 | ## Next Steps
45 |
46 | Please visit the [Wiki](https://github.com/rwth-acis/las2peer-Template-Project/wiki/) of this project.
47 | There you will find guides and tutorials, information on las2peer concepts and further interesting las2peer knowledge.
48 |
--------------------------------------------------------------------------------
/bin/.gitignore:
--------------------------------------------------------------------------------
1 | start_network.bat
2 | start_network.sh
3 |
--------------------------------------------------------------------------------
/bin/start_ServiceAgentGenerator.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | cd %~dp0
4 | cd ..
5 | set BASE=%CD%
6 | set CLASSPATH="%BASE%/lib/*;"
7 |
8 | if "%~2"=="" (
9 | echo Syntax error!
10 | echo.
11 | echo Usage: start_ServiceAgentGenerator service.canonical.class.name service.password
12 | ) else (
13 | java -cp %CLASSPATH% i5.las2peer.tools.ServiceAgentGenerator %1 %2
14 | )
15 |
--------------------------------------------------------------------------------
/bin/start_ServiceAgentGenerator.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # this scripts generates a xml file for the specified ServiceClass with the desired ServicePass
4 | # pls run the script form the root folder of your deployment, e. g. ./bin/start_ServiceAgentGenerator.sh
5 |
6 | java -cp "lib/*" i5.las2peer.tools.ServiceAgentGenerator "$@"
7 |
--------------------------------------------------------------------------------
/bin/start_UserAgentGenerator.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | cd %~dp0
4 | cd ..
5 | set BASE=%CD%
6 | set CLASSPATH="%BASE%/lib/*"
7 |
8 | if "%~2"=="" (
9 | echo Syntax error!
10 | echo.
11 | echo Usage: start_UserAgentGenerator user.name user.password user.mail
12 | ) else (
13 | java -cp %CLASSPATH% i5.las2peer.tools.UserAgentGenerator %2 %1 %3
14 | )
--------------------------------------------------------------------------------
/bin/start_UserAgentGenerator.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # this scripts generates an user agent as xml file in order to upload it via the startup folder
4 | # pls run the script form the root folder of your deployment, e. g. ./bin/start_UserAgentGenerator.sh
5 |
6 | java -cp "lib/*" i5.las2peer.tools.UserAgentGenerator "$@"
7 |
--------------------------------------------------------------------------------
/docker-entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | # print all comands to console if DEBUG is set
6 | if [[ ! -z "${DEBUG}" ]]; then
7 | set -x
8 | fi
9 | NODE_ID_SEED=${NODE_ID_SEED:-$RANDOM}
10 |
11 | # set some helpful variables
12 | export SERVICE_PROPERTY_FILE='etc/i5.las2peer.services.servicePackage.TemplateService.properties'
13 | export WEB_CONNECTOR_PROPERTY_FILE='etc/i5.las2peer.connectors.webConnector.WebConnector.properties'
14 | export SERVICE_VERSION=$(awk -F "=" '/service.version/ {print $2}' gradle.properties)
15 | export SERVICE_NAME=$(awk -F "=" '/service.name/ {print $2}' gradle.properties)
16 | export SERVICE_CLASS=$(awk -F "=" '/service.class/ {print $2}' gradle.properties)
17 | export SERVICE=${SERVICE_NAME}.${SERVICE_CLASS}@${SERVICE_VERSION}
18 |
19 | function set_in_service_config {
20 | sed -i "s?${1}[[:blank:]]*=.*?${1}=${2}?g" ${SERVICE_PROPERTY_FILE}
21 | }
22 |
23 |
24 | # set defaults for optional service parameters
25 | [[ -z "${SERVICE_PASSPHRASE}" ]] && export SERVICE_PASSPHRASE='template'
26 |
27 | # wait for any bootstrap host to be available
28 | if [[ ! -z "${BOOTSTRAP}" ]]; then
29 | echo "Waiting for any bootstrap host to become available..."
30 | for host_port in ${BOOTSTRAP//,/ }; do
31 | arr_host_port=(${host_port//:/ })
32 | host=${arr_host_port[0]}
33 | port=${arr_host_port[1]}
34 | if { /dev/null; then
35 | echo "${host_port} is available. Continuing..."
36 | break
37 | fi
38 | done
39 | fi
40 | # prevent glob expansion in lib/*
41 | set -f
42 | LAUNCH_COMMAND='java -cp lib/* --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED i5.las2peer.tools.L2pNodeLauncher -s service -p '"${LAS2PEER_PORT} ${SERVICE_EXTRA_ARGS}"
43 | if [[ ! -z "${BOOTSTRAP}" ]]; then
44 | LAUNCH_COMMAND="${LAUNCH_COMMAND} -b ${BOOTSTRAP}"
45 | fi
46 |
47 | # it's realistic for different nodes to use different accounts (i.e., to have
48 | # different node operators). this function echos the N-th mnemonic if the
49 | # variable WALLET is set to N. If not, first mnemonic is used
50 | function selectMnemonic {
51 | declare -a mnemonics=("differ employ cook sport clinic wedding melody column pave stuff oak price" "memory wrist half aunt shrug elbow upper anxiety maximum valve finish stay" "alert sword real code safe divorce firm detect donate cupboard forward other" "pair stem change april else stage resource accident will divert voyage lawn" "lamp elbow happy never cake very weird mix episode either chimney episode" "cool pioneer toe kiwi decline receive stamp write boy border check retire" "obvious lady prize shrimp taste position abstract promote market wink silver proof" "tired office manage bird scheme gorilla siren food abandon mansion field caution" "resemble cattle regret priority hen six century hungry rice grape patch family" "access crazy can job volume utility dial position shaft stadium soccer seven")
52 | if [[ ${WALLET} =~ ^[0-9]+$ && ${WALLET} -lt ${#mnemonics[@]} ]]; then
53 | # get N-th mnemonic
54 | echo "${mnemonics[${WALLET}]}"
55 | else
56 | # note: zsh and others use 1-based indexing. this requires bash
57 | echo "${mnemonics[0]}"
58 | fi
59 | }
60 |
61 | #prepare pastry properties
62 | echo external_address = $(curl -s https://ipinfo.io/ip):${LAS2PEER_PORT} > etc/pastry.properties
63 |
64 | # start the service within a las2peer node
65 | if [[ -z "${@}" ]]
66 | then
67 | if [ -n "$LAS2PEER_ETH_HOST" ]; then
68 | exec ${LAUNCH_COMMAND} --node-id-seed $NODE_ID_SEED --observer --ethereum-mnemonic "$(selectMnemonic)" uploadStartupDirectory startService\("'""${SERVICE}""'", "'""${SERVICE_PASSPHRASE}""'"\) startWebConnector "node=getNodeAsEthereumNode()" "registry=node.getRegistryClient()" "n=getNodeAsEthereumNode()" "r=n.getRegistryClient()"
69 | else
70 | exec ${LAUNCH_COMMAND} --node-id-seed $NODE_ID_SEED --observer uploadStartupDirectory startService\("'""${SERVICE}""'", "'""${SERVICE_PASSPHRASE}""'"\) startWebConnector
71 | fi
72 | else
73 | exec ${LAUNCH_COMMAND} ${@}
74 | fi
--------------------------------------------------------------------------------
/etc/i5.las2peer.connectors.webConnector.WebConnector.properties:
--------------------------------------------------------------------------------
1 | httpPort = 8080
2 | httpsPort = 8090
3 | startHttp = TRUE
4 | startHttps = FALSE
5 | sslKeystore = etc/example.jks
6 | sslKeyPassword = secretpassword
7 | crossOriginResourceDomain = *
8 | crossOriginResourceMaxAge = 60
9 | enableCrossOriginResourceSharing = TRUE
10 | onlyLocalServices = FALSE
11 | defaultLoginUser = anonymous
12 | defaultLoginPassword = anonymous
13 | oidcProviders = https://auth.las2peer.org/auth/realms/main,https://accounts.google.com
14 |
--------------------------------------------------------------------------------
/etc/i5.las2peer.services.servicePackage.TemplateService.properties:
--------------------------------------------------------------------------------
1 | templateProperty="Insert your properties here"
2 |
--------------------------------------------------------------------------------
/etc/nodeInfo.xml:
--------------------------------------------------------------------------------
1 |
2 | Admin
3 | admin@mail.com
4 | Advanced Community Information Systems (ACIS) Group, RWTH Aachen University
5 | This node hosts a sample service.
6 |
7 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | core.version=1.2.2
2 | service.name=i5.las2peer.services.templateService
3 | service.class=TemplateService
4 | service.version=1.0.0
5 | java.version=17
6 |
7 | las2peer_user1.name=alice
8 | las2peer_user1.password=pwalice
9 | las2peer_user1.email=alice@example.org
10 | las2peer_user2.name=bobby
11 | las2peer_user2.password=pwbobby
12 | las2peer_user2.email=bobby@example.org
13 | las2peer_user3.name=joey
14 | las2peer_user3.password=pwjoey
15 | las2peer_user3.email=joey@example.org
16 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rwth-acis/las2peer-template-project/ac9b496a6e8030afe613e3b4d1ef0552e993c147/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rwth-acis/las2peer-template-project/ac9b496a6e8030afe613e3b4d1ef0552e993c147/gradlew
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'las2peer-template-project'
2 | include('template_project')
3 |
--------------------------------------------------------------------------------
/template_project/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | // Apply the application plugin to add support for building a CLI application in Java.
3 | id 'application'
4 | id 'eclipse'
5 | id 'jacoco'
6 | }
7 |
8 | repositories {
9 | // Use maven central for resolving dependencies.
10 | mavenCentral()
11 |
12 | // DBIS Archiva
13 | maven {
14 | url "https://archiva.dbis.rwth-aachen.de:9911/repository/internal/"
15 | }
16 | }
17 |
18 |
19 | dependencies {
20 | // Use JUnit test framework.
21 | testImplementation "junit:junit:4.13.2"
22 |
23 | // las2peer bundle which is not necessary in the runtime path
24 | // compileOnly will be moved into the lib dir afterwards
25 | compileOnly "i5:las2peer-bundle:${project.property('core.version')}"
26 |
27 | // Add service dependencies here
28 | // example:
29 | // implementation "net.minidev:json-smart:1.3.1"
30 | }
31 |
32 | configurations {
33 | // This ensures las2peer is available in the tests, but won't be bundled
34 | testImplementation.extendsFrom compileOnly
35 | }
36 |
37 | jar {
38 | manifest {
39 | attributes "Main-Class": "${project.property('service.name')}.${project.property('service.class')}"
40 | attributes "Library-Version": "${project.property('service.version')}"
41 | attributes "Library-SymbolicName": "${project.property('service.name')}"
42 | }
43 |
44 | from { (configurations.runtimeClasspath).collect { it.isDirectory() ? it : zipTree(it) } } {
45 | // Exclude signatures to be able to natively bundle signed jars
46 | exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
47 | }
48 | }
49 |
50 | application {
51 | // Define the main class for the application.
52 | mainClass = "${project.property('service.name')}.${project.property('service.class')}"
53 |
54 | group = "${project.property('service.name')}"
55 | archivesBaseName = group
56 |
57 | version = "${project.property('service.version')}"
58 | mainClass.set("i5.las2peer.tools.L2pNodeLauncher")
59 | sourceCompatibility = "${project.property('java.version')}"
60 | targetCompatibility = "${project.property('java.version')}"
61 | }
62 |
63 | // put all .jar files into export/jars folder
64 | tasks.withType(Jar) {
65 | destinationDirectory = file("$projectDir/export/jars")
66 | }
67 |
68 | javadoc {
69 | destinationDir = file("$projectDir/export/doc")
70 | }
71 |
72 | build.dependsOn "javadoc"
73 |
74 | compileJava {
75 | dependsOn "copyMain"
76 | }
77 |
78 | compileTestJava {
79 | dependsOn "copyTest"
80 | }
81 |
82 | // Copies .xml files into build directory
83 | task copyMain(type: Copy) {
84 | from "src/main/java"
85 | include "**/*.xml"
86 | into "$buildDir/classes/java/main"
87 | }
88 |
89 | // Copies .xml files into build directory
90 | task copyTest(type: Copy) {
91 | from "src/test/java"
92 | include "**/*.xml"
93 | into "$buildDir/classes/java/test"
94 | }
95 |
96 | // These two tasks restore the build and runtime environment used
97 | // in the ant environment
98 | task copyJar(type: Copy) {
99 | from jar // here it automatically reads jar file produced from jar task
100 | into "$rootDir/service"
101 | }
102 |
103 | task copyToLib(type: Copy) {
104 | from configurations.compileClasspath
105 | into "$rootDir/lib"
106 | }
107 |
108 | build.dependsOn copyJar
109 | build.dependsOn copyToLib
110 |
111 | task startscripts {
112 | new File("$rootDir/bin", "start_network.sh").text = """#!/bin/bash
113 |
114 | # this script is autogenerated by 'gradle startscripts'
115 | # it starts a las2peer node providing the service '${project.property('service.name')}.${project.property('service.class')}' of this project
116 | # pls execute it from the root folder of your deployment, e. g. ./bin/start_network.sh
117 |
118 | java -cp "lib/*" --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED i5.las2peer.tools.L2pNodeLauncher --port 9011 --service-directory service uploadStartupDirectory startService\\(\\'${project.property('service.name')}.${project.property('service.class')}@${project.property('service.version')}\\'\\) startWebConnector interactive
119 | """
120 | new File("$rootDir/bin", "start_network.bat").text = """:: this script is autogenerated by 'gradle startscripts'
121 | :: it starts a las2peer node providing the service '${project.property('service.name')}.${project.property('service.class')}' of this project
122 | :: pls execute it from the bin folder of your deployment by double-clicking on it
123 |
124 | %~d0
125 | cd %~p0
126 | cd ..
127 | set BASE=%CD%
128 | set CLASSPATH="%BASE%/lib/*;"
129 | set ADD_OPENS=--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED
130 |
131 | java -cp %CLASSPATH% %ADD_OPENS% i5.las2peer.tools.L2pNodeLauncher --port 9011 --service-directory service uploadStartupDirectory startService('${project.property('service.name')}.${project.property('service.class')}@${project.property('service.version')}') startWebConnector interactive
132 |
133 | pause
134 | """
135 | }
136 |
137 | build.dependsOn "startscripts"
138 |
139 | def startup = "$rootDir/etc/startup"
140 | def userAgent1Path = "${startup}/agent-user-${project.property('las2peer_user1.name')}.xml"
141 | def userAgent2Path = "${startup}/agent-user-${project.property('las2peer_user2.name')}.xml"
142 | def userAgent3Path = "${startup}/agent-user-${project.property('las2peer_user3.name')}.xml"
143 | def passphrasesPath = "${startup}/passphrases.txt"
144 |
145 | task generateUserAgent1 {
146 | dependsOn "jar"
147 |
148 | onlyIf { !(new File(userAgent1Path).exists()) }
149 |
150 | doLast {
151 | tasks.create("generateUserAgent1Help", JavaExec) {
152 | println "Writing User Agent xml to ${userAgent1Path}"
153 |
154 | main = "i5.las2peer.tools.UserAgentGenerator"
155 | classpath = sourceSets.main.compileClasspath
156 | args "${project.property('las2peer_user1.password')}", "${project.property('las2peer_user1.name')}", "${project.property('las2peer_user1.email')}"
157 | mkdir "${startup}"
158 | standardOutput new FileOutputStream(userAgent1Path)
159 | }.exec()
160 | }
161 | }
162 |
163 | task generateUserAgent2 {
164 | dependsOn "jar"
165 |
166 | onlyIf { !(new File(userAgent2Path).exists()) }
167 |
168 | doLast {
169 | tasks.create("generateUserAgent2Help", JavaExec) {
170 | println "Writing User Agent xml to ${userAgent2Path}"
171 |
172 | main = "i5.las2peer.tools.UserAgentGenerator"
173 | classpath = sourceSets.main.compileClasspath
174 | args "${project.property('las2peer_user2.password')}", "${project.property('las2peer_user2.name')}", "${project.property('las2peer_user2.email')}"
175 | mkdir "${startup}"
176 | standardOutput new FileOutputStream(userAgent2Path)
177 | }.exec()
178 | }
179 | }
180 |
181 | task generateUserAgent3 {
182 | dependsOn "jar"
183 |
184 | onlyIf { !(new File(userAgent3Path).exists()) }
185 |
186 | doLast {
187 | tasks.create("generateUserAgent3Help", JavaExec) {
188 | println "Writing User Agent xml to ${userAgent3Path}"
189 |
190 | main = "i5.las2peer.tools.UserAgentGenerator"
191 | classpath = sourceSets.main.compileClasspath
192 | args "${project.property('las2peer_user3.password')}", "${project.property('las2peer_user3.name')}", "${project.property('las2peer_user3.email')}"
193 | mkdir "${startup}"
194 | standardOutput new FileOutputStream(userAgent3Path)
195 | }.exec()
196 | }
197 | }
198 |
199 | // generate example user agents
200 | task generateAgents {
201 | description "Generate example user agents"
202 | dependsOn "generateUserAgent1"
203 | dependsOn "generateUserAgent2"
204 | dependsOn "generateUserAgent3"
205 |
206 | doLast {
207 | new File(passphrasesPath).text = """agent-user-${project.property('las2peer_user1.name')}.xml;${project.property('las2peer_user1.password')}
208 | agent-user-${project.property('las2peer_user2.name')}.xml;${project.property('las2peer_user2.password')}
209 | agent-user-${project.property('las2peer_user3.name')}.xml;${project.property('las2peer_user3.password')}
210 | """
211 | }
212 | }
213 |
214 | task deleteStartup {
215 |
216 | file("$rootDir/etc/startup").deleteDir()
217 |
218 | }
219 |
220 | build.dependsOn "deleteStartup"
221 |
222 | build.dependsOn "generateAgents"
223 |
224 | clean.doLast {
225 | file("$rootDir/tmp").deleteDir()
226 | file("$rootDir/lib").deleteDir()
227 | file("$rootDir/servicebundle").deleteDir()
228 | file("$rootDir/service").deleteDir()
229 | file("$rootDir/etc/startup").deleteDir()
230 | file("$projectDir/export").deleteDir()
231 | }
232 |
233 | task cleanAll {
234 | dependsOn "clean"
235 |
236 | doLast {
237 | file("$rootDir/log").deleteDir()
238 | file("$rootDir/node-storage").deleteDir()
239 | }
240 | }
241 |
242 | jacoco {
243 | toolVersion = "0.8.7"
244 | reportsDirectory = file("$projectDir/export/jacoco")
245 | }
246 |
247 | test {
248 | finalizedBy jacocoTestReport // report is always generated after tests run
249 |
250 | jacoco {
251 | destinationFile = file("$projectDir/export/jacoco.exec")
252 | }
253 | }
254 |
255 | jacocoTestReport {
256 | dependsOn test // tests are required to run before generating the report
257 |
258 | // enable the xml report (html is also enabled)
259 | reports {
260 | xml.enabled true
261 | }
262 | }
263 |
264 | // configuration for eclipse (this allows to import the template project as a gradle project in eclipse without any problems)
265 | eclipse {
266 | classpath {
267 | file {
268 | whenMerged {
269 | // change output directory for test, main, resources and default
270 | def main = entries.find { it.path == "src/main/java" }
271 | main.output = "output/main"
272 |
273 | def test = entries.find { it.path == "src/test/java" }
274 | test.output = "output/test"
275 |
276 | def defaultEntry = entries.find { it.kind == "output" && it.path == "bin/default" }
277 | defaultEntry.path = "output/default"
278 | }
279 | }
280 | }
281 | }
--------------------------------------------------------------------------------
/template_project/src/main/java/i5/las2peer/services/templateService/TemplateService.java:
--------------------------------------------------------------------------------
1 | package i5.las2peer.services.templateService;
2 |
3 | import java.net.HttpURLConnection;
4 |
5 | import javax.ws.rs.GET;
6 | import javax.ws.rs.POST;
7 | import javax.ws.rs.Path;
8 | import javax.ws.rs.PathParam;
9 | import javax.ws.rs.Produces;
10 | import javax.ws.rs.core.MediaType;
11 | import javax.ws.rs.core.Response;
12 |
13 | import i5.las2peer.api.Context;
14 | import i5.las2peer.api.security.UserAgent;
15 | import i5.las2peer.restMapper.RESTService;
16 | import i5.las2peer.restMapper.annotations.ServicePath;
17 | import io.swagger.annotations.Api;
18 | import io.swagger.annotations.ApiOperation;
19 | import io.swagger.annotations.ApiResponse;
20 | import io.swagger.annotations.ApiResponses;
21 | import io.swagger.annotations.Contact;
22 | import io.swagger.annotations.Info;
23 | import io.swagger.annotations.License;
24 | import io.swagger.annotations.SwaggerDefinition;
25 |
26 | // TODO Describe your own service
27 | /**
28 | * las2peer-Template-Service
29 | *
30 | * This is a template for a very basic las2peer service that uses the las2peer WebConnector for RESTful access to it.
31 | *
32 | * Note: If you plan on using Swagger you should adapt the information below in the SwaggerDefinition annotation to suit
33 | * your project. If you do not intend to provide a Swagger documentation of your service API, the entire Api and
34 | * SwaggerDefinition annotation should be removed.
35 | *
36 | */
37 | // TODO Adjust the following configuration
38 | @Api
39 | @SwaggerDefinition(
40 | info = @Info(
41 | title = "las2peer Template Service",
42 | version = "1.0.0",
43 | description = "A las2peer Template Service for demonstration purposes.",
44 | termsOfService = "http://your-terms-of-service-url.com",
45 | contact = @Contact(
46 | name = "John Doe",
47 | url = "provider.com",
48 | email = "john.doe@provider.com"),
49 | license = @License(
50 | name = "your software license name",
51 | url = "http://your-software-license-url.com")))
52 | @ServicePath("/template")
53 | // TODO Your own service class
54 | public class TemplateService extends RESTService {
55 |
56 | /**
57 | * Template of a get function.
58 | *
59 | * @return Returns an HTTP response with the username as string content.
60 | */
61 | @GET
62 | @Path("/get")
63 | @Produces(MediaType.TEXT_PLAIN)
64 | @ApiOperation(
65 | value = "REPLACE THIS WITH AN APPROPRIATE FUNCTION NAME",
66 | notes = "REPLACE THIS WITH YOUR NOTES TO THE FUNCTION")
67 | @ApiResponses(
68 | value = { @ApiResponse(
69 | code = HttpURLConnection.HTTP_OK,
70 | message = "REPLACE THIS WITH YOUR OK MESSAGE") })
71 | public Response getTemplate() {
72 | UserAgent userAgent = (UserAgent) Context.getCurrent().getMainAgent();
73 | String name = userAgent.getLoginName();
74 | return Response.ok().entity(name).build();
75 | }
76 |
77 | /**
78 | * Template of a post function.
79 | *
80 | * @param myInput The post input the user will provide.
81 | * @return Returns an HTTP response with plain text string content derived from the path input param.
82 | */
83 | @POST
84 | @Path("/post/{input}")
85 | @Produces(MediaType.TEXT_PLAIN)
86 | @ApiResponses(
87 | value = { @ApiResponse(
88 | code = HttpURLConnection.HTTP_OK,
89 | message = "REPLACE THIS WITH YOUR OK MESSAGE") })
90 | @ApiOperation(
91 | value = "REPLACE THIS WITH AN APPROPRIATE FUNCTION NAME",
92 | notes = "Example method that returns a phrase containing the received input.")
93 | public Response postTemplate(@PathParam("input") String myInput) {
94 | String returnString = "";
95 | returnString += "Input " + myInput;
96 | return Response.ok().entity(returnString).build();
97 | }
98 |
99 | // TODO your own service methods, e. g. for RMI
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/template_project/src/test/java/i5/las2peer/services/templateService/ServiceTest.java:
--------------------------------------------------------------------------------
1 | package i5.las2peer.services.templateService;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.PrintStream;
5 |
6 | import org.junit.After;
7 | import org.junit.Assert;
8 | import org.junit.Before;
9 | import org.junit.Test;
10 |
11 | import i5.las2peer.api.p2p.ServiceNameVersion;
12 | import i5.las2peer.connectors.webConnector.WebConnector;
13 | import i5.las2peer.connectors.webConnector.client.ClientResponse;
14 | import i5.las2peer.connectors.webConnector.client.MiniClient;
15 | import i5.las2peer.p2p.LocalNode;
16 | import i5.las2peer.p2p.LocalNodeManager;
17 | import i5.las2peer.security.UserAgentImpl;
18 | import i5.las2peer.testing.MockAgentFactory;
19 |
20 | /**
21 | * Example Test Class demonstrating a basic JUnit test structure.
22 | *
23 | */
24 | public class ServiceTest {
25 |
26 |
27 | private static LocalNode node;
28 | private static WebConnector connector;
29 | private static ByteArrayOutputStream logStream;
30 |
31 | private static UserAgentImpl testAgent;
32 | private static final String testPass = "adamspass";
33 |
34 | private static final String mainPath = "template/";
35 |
36 | /**
37 | * Called before a test starts.
38 | *
39 | * Sets up the node, initializes connector and adds user agent that can be used throughout the test.
40 | *
41 | * @throws Exception
42 | */
43 | @Before
44 | public void startServer() throws Exception {
45 | // start node
46 | node = new LocalNodeManager().newNode();
47 | node.launch();
48 |
49 | // add agent to node
50 | testAgent = MockAgentFactory.getAdam();
51 | testAgent.unlock(testPass); // agents must be unlocked in order to be stored
52 | node.storeAgent(testAgent);
53 |
54 | // start service
55 | // during testing, the specified service version does not matter
56 | node.startService(new ServiceNameVersion(TemplateService.class.getName(), "1.0.0"), "a pass");
57 |
58 | // start connector
59 | connector = new WebConnector(true, 0, false, 0); // port 0 means use system defined port
60 | logStream = new ByteArrayOutputStream();
61 | connector.setLogStream(new PrintStream(logStream));
62 | connector.start(node);
63 | }
64 |
65 | /**
66 | * Called after the test has finished. Shuts down the server and prints out the connector log file for reference.
67 | *
68 | * @throws Exception
69 | */
70 | @After
71 | public void shutDownServer() throws Exception {
72 | if (connector != null) {
73 | connector.stop();
74 | connector = null;
75 | }
76 | if (node != null) {
77 | node.shutDown();
78 | node = null;
79 | }
80 | if (logStream != null) {
81 | System.out.println("Connector-Log:");
82 | System.out.println("--------------");
83 | System.out.println(logStream.toString());
84 | logStream = null;
85 | }
86 | }
87 |
88 | /**
89 | *
90 | * Tests the validation method.
91 | *
92 | */
93 | @Test
94 | public void testGet() {
95 | try {
96 | MiniClient client = new MiniClient();
97 | client.setConnectorEndpoint(connector.getHttpEndpoint());
98 | client.setLogin(testAgent.getIdentifier(), testPass);
99 |
100 | ClientResponse result = client.sendRequest("GET", mainPath + "get", "");
101 | Assert.assertEquals(200, result.getHttpCode());
102 | Assert.assertEquals("adam", result.getResponse().trim());// YOUR RESULT VALUE HERE
103 | System.out.println("Result of 'testGet': " + result.getResponse().trim());
104 | } catch (Exception e) {
105 | e.printStackTrace();
106 | Assert.fail(e.toString());
107 | }
108 | }
109 |
110 | /**
111 | *
112 | * Test the example method that consumes one path parameter which we give the value "testInput" in this test.
113 | *
114 | */
115 | @Test
116 | public void testPost() {
117 | try {
118 | MiniClient client = new MiniClient();
119 | client.setConnectorEndpoint(connector.getHttpEndpoint());
120 | client.setLogin(testAgent.getIdentifier(), testPass);
121 |
122 | // testInput is the pathParam
123 | ClientResponse result = client.sendRequest("POST", mainPath + "post/testInput", "");
124 | Assert.assertEquals(200, result.getHttpCode());
125 | // "testInput" name is part of response
126 | Assert.assertTrue(result.getResponse().trim().contains("testInput"));
127 | System.out.println("Result of 'testPost': " + result.getResponse().trim());
128 | } catch (Exception e) {
129 | e.printStackTrace();
130 | Assert.fail(e.toString());
131 | }
132 | }
133 |
134 | }
135 |
--------------------------------------------------------------------------------