├── .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 | ![Java CI with Gradle](https://github.com/rwth-acis/las2peer-template-project/workflows/Java%20CI%20with%20Gradle/badge.svg?branch=master) 7 | [![codecov](https://codecov.io/gh/rwth-acis/las2peer-template-project/branch/master/graph/badge.svg)](https://codecov.io/gh/rwth-acis/las2peer-template-project) 8 | [![Dependencies](https://img.shields.io/librariesio/github/rwth-acis/las2peer-template-project)](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 | --------------------------------------------------------------------------------