Initial commit
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b377fd1 --- /dev/null +++ b/.gitignore
@@ -0,0 +1,15 @@ +.git +.idea/**/*.xml +.settings +.classpath +target +/.idea/compiler.xml +/.idea/*.xml +/.idea/modules.xml +/.idea/vcs.xml +/bin/ +*.iml +.project +.classpath +.idea +/dependency-reduced-pom.xml
diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c9ab737 --- /dev/null +++ b/Dockerfile
@@ -0,0 +1,21 @@ +FROM myserver:withproxy +#linux 16.04 +MAINTAINER Dimitris + +WORKDIR microservices + +RUN git clone http://172.18.22.160:8880/gitblit-1.8.0/r/Dropwizard/Microservices/mics-central-service.git && cd mics-central-service && git checkout DEVELOP_BE + +WORKDIR mics-central-service + +RUN mvn install -DskipTests + +WORKDIR / + +COPY my_wrapper_script.sh my_wrapper_script.sh +RUN sed -i -e 's/\r$//' my_wrapper_script.sh +CMD ./my_wrapper_script.sh + +EXPOSE 9010 9011 + +
diff --git a/How_to_dockerize_documentation.docx b/How_to_dockerize_documentation.docx new file mode 100644 index 0000000..84b581e --- /dev/null +++ b/How_to_dockerize_documentation.docx Binary files differ
diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..0db6dd9 --- /dev/null +++ b/Jenkinsfile
@@ -0,0 +1,18 @@ +node { + + stage('Clone repository') { + /* Let's make sure we have the repository cloned to our workspace */ + + checkout scm + } + + stage('Build image') { + /* This builds the actual image; synonymous to + * docker build on the command line */ + sh 'docker build --rm --no-cache -t myserver_central:jenkinsversion .' + } + + stage('Refresh containers') { + bat 'start cmd.exe /c C:\\Jenkinshelper\\refresh_docker.bat' + } +} \ No newline at end of file
diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..11ecb79 --- /dev/null +++ b/LICENSE.md
@@ -0,0 +1,198 @@ +Eclipse Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC +LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM +CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and documentation + distributed under this Agreement, and +b) in the case of each subsequent Contributor: + i) changes to the Program, and + ii) additions to the Program; + + where such changes and/or additions to the Program originate from and are + distributed by that particular Contributor. A Contribution 'originates' from + a Contributor if it was added to the Program by such Contributor itself or + anyone acting on such Contributor's behalf. Contributions do not include + additions to the Program which: (i) are separate modules of software + distributed in conjunction with the Program under their own license + agreement, and (ii) are not derivative works of the Program. + +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which are +necessarily infringed by the use or sale of its Contribution alone or when +combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, +including all Contributors. + +2. GRANT OF RIGHTS + a) Subject to the terms of this Agreement, each Contributor hereby grants + Recipient a non-exclusive, worldwide, royalty-free copyright license to + reproduce, prepare derivative works of, publicly display, publicly perform, + distribute and sublicense the Contribution of such Contributor, if any, and + such derivative works, in source code and object code form. + b) Subject to the terms of this Agreement, each Contributor hereby grants + Recipient a non-exclusive, worldwide, royalty-free patent license under + Licensed Patents to make, use, sell, offer to sell, import and otherwise + transfer the Contribution of such Contributor, if any, in source code and + object code form. This patent license shall apply to the combination of the + Contribution and the Program if, at the time the Contribution is added by + the Contributor, such addition of the Contribution causes such combination + to be covered by the Licensed Patents. The patent license shall not apply + to any other combinations which include the Contribution. No hardware per + se is licensed hereunder. + c) Recipient understands that although each Contributor grants the licenses to + its Contributions set forth herein, no assurances are provided by any + Contributor that the Program does not infringe the patent or other + intellectual property rights of any other entity. Each Contributor + disclaims any liability to Recipient for claims brought by any other entity + based on infringement of intellectual property rights or otherwise. As a + condition to exercising the rights and licenses granted hereunder, each + Recipient hereby assumes sole responsibility to secure any other + intellectual property rights needed, if any. For example, if a third party + patent license is required to allow Recipient to distribute the Program, it + is Recipient's responsibility to acquire that license before distributing + the Program. + d) Each Contributor represents that to its knowledge it has sufficient + copyright rights in its Contribution, if any, to grant the copyright + license set forth in this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under its +own license agreement, provided that: + + a) it complies with the terms and conditions of this Agreement; and + b) its license agreement: + i) effectively disclaims on behalf of all Contributors all warranties and + conditions, express and implied, including warranties or conditions of + title and non-infringement, and implied warranties or conditions of + merchantability and fitness for a particular purpose; + ii) effectively excludes on behalf of all Contributors all liability for + damages, including direct, indirect, special, incidental and + consequential damages, such as lost profits; + iii) states that any provisions which differ from this Agreement are offered + by that Contributor alone and not by any other party; and + iv) states that source code for the Program is available from such + Contributor, and informs licensees how to obtain it in a reasonable + manner on or through a medium customarily used for software exchange. + +When the Program is made available in source code form: + + a) it must be made available under this Agreement; and + b) a copy of this Agreement must be included with each copy of the Program. + Contributors may not remove or alter any copyright notices contained within + the Program. + +Each Contributor must identify itself as the originator of its Contribution, if +any, in a manner that reasonably allows subsequent Recipients to identify the +originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with +respect to end users, business partners and the like. While this license is +intended to facilitate the commercial use of the Program, the Contributor who +includes the Program in a commercial product offering should do so in a manner +which does not create potential liability for other Contributors. Therefore, if +a Contributor includes the Program in a commercial product offering, such +Contributor ("Commercial Contributor") hereby agrees to defend and indemnify +every other Contributor ("Indemnified Contributor") against any losses, damages +and costs (collectively "Losses") arising from claims, lawsuits and other legal +actions brought by a third party against the Indemnified Contributor to the +extent caused by the acts or omissions of such Commercial Contributor in +connection with its distribution of the Program in a commercial product +offering. The obligations in this section do not apply to any claims or Losses +relating to any actual or alleged intellectual property infringement. In order +to qualify, an Indemnified Contributor must: a) promptly notify the Commercial +Contributor in writing of such claim, and b) allow the Commercial Contributor to +control, and cooperate with the Commercial Contributor in, the defense and any +related settlement negotiations. The Indemnified Contributor may participate in +any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product +offering, Product X. That Contributor is then a Commercial Contributor. If that +Commercial Contributor then makes performance claims, or offers warranties +related to Product X, those performance claims and warranties are such +Commercial Contributor's responsibility alone. Under this section, the +Commercial Contributor would have to defend claims against the other +Contributors related to those performance claims and warranties, and if a court +requires any other Contributor to pay any damages as a result, the Commercial +Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR +IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, +NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each +Recipient is solely responsible for determining the appropriateness of using and +distributing the Program and assumes all risks associated with its exercise of +rights under this Agreement , including but not limited to the risks and costs +of program errors, compliance with applicable laws, damage to or loss of data, +programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY +CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST +PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS +GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable +law, it shall not affect the validity or enforceability of the remainder of the +terms of this Agreement, and without further action by the parties hereto, such +provision shall be reformed to the minimum extent necessary to make such +provision valid and enforceable. + +If Recipient institutes patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Program itself +(excluding combinations of the Program with other software or hardware) +infringes such Recipient's patent(s), then such Recipient's rights granted under +Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to +comply with any of the material terms or conditions of this Agreement and does +not cure such failure in a reasonable period of time after becoming aware of +such noncompliance. If all Recipient's rights under this Agreement terminate, +Recipient agrees to cease use and distribution of the Program as soon as +reasonably practicable. However, Recipient's obligations under this Agreement +and any licenses granted by Recipient relating to the Program shall continue and +survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in +order to avoid inconsistency the Agreement is copyrighted and may only be +modified in the following manner. The Agreement Steward reserves the right to +publish new versions (including revisions) of this Agreement from time to time. +No one other than the Agreement Steward has the right to modify this Agreement. +The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation +may assign the responsibility to serve as the Agreement Steward to a suitable +separate entity. Each new version of the Agreement will be given a +distinguishing version number. The Program (including Contributions) may always +be distributed subject to the version of the Agreement under which it was +received. In addition, after a new version of the Agreement is published, +Contributor may elect to distribute the Program (including its Contributions) +under the new version. Except as expressly stated in Sections 2(a) and 2(b) +above, Recipient receives no rights or licenses to the intellectual property of +any Contributor under this Agreement, whether expressly, by implication, +estoppel or otherwise. All rights in the Program not expressly granted under +this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the +intellectual property laws of the United States of America. No party to this +Agreement will bring a legal action under this Agreement more than one year +after the cause of action arose. Each party waives its rights to a jury trial in +any resulting litigation.
diff --git a/README.md b/README.md new file mode 100644 index 0000000..fc24ab4 --- /dev/null +++ b/README.md
@@ -0,0 +1,13 @@ +# micsCentral + +How to start the micsCentral application +--- + +1. Run `mvn clean install` to build your application +1. Start application with `java -jar target/mics-central-service-0.1.1-SNAPSHOT.jar server config.yml` +1. To check that your application is running enter url `http://localhost:8080` + +Health Check +--- + +To see your applications health enter url `http://localhost:8081/healthcheck`
diff --git a/my_wrapper_script.sh b/my_wrapper_script.sh new file mode 100644 index 0000000..b332df0 --- /dev/null +++ b/my_wrapper_script.sh
@@ -0,0 +1,4 @@ +#!/bin/bash + +cd microservices/mics-central-service/ +java -jar target/mics-central-service.jar server serviceConfigDocker.yml \ No newline at end of file
diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..e3768dd --- /dev/null +++ b/pom.xml
@@ -0,0 +1,288 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + <prerequisites> + <maven>3.0.0</maven> + </prerequisites> + + <groupId>org.eclipse.openk</groupId> + <artifactId>mics-central-service</artifactId> + <version>0.1.3-SNAPSHOT</version> + <packaging>jar</packaging> + + <name>mics-central-service</name> + + <properties> + <java-source-target-version>1.8</java-source-target-version> + <maven.test.skip>false</maven.test.skip> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> + <mainClass>org.eclipse.openk.MicsCentralApplication</mainClass> + + <dropwizard.version>1.3.1</dropwizard.version> + <easymock.version>3.4</easymock.version> + <powermock-api-easymock.version>1.6.6</powermock-api-easymock.version> + <jacoco-maven-plugin.version>0.7.9</jacoco-maven-plugin.version> + <sonar-maven-plugin.version>3.2</sonar-maven-plugin.version> + <commons-io.version>2.5</commons-io.version> + <gson.version>2.8.5</gson.version> + <httpclient.version>4.5.3</httpclient.version> + <swagger-maven-plugin-version>3.1.6</swagger-maven-plugin-version> + <swagger-jersey2-jaxrs>1.5.12</swagger-jersey2-jaxrs> + <maven-shade-plugin.version>2.4.1</maven-shade-plugin.version> + <maven-jar-plugin-version>2.6</maven-jar-plugin-version> + <maven-compiler-plugin-version>3.6.1</maven-compiler-plugin-version> + <maven-source-plugin-version>2.4</maven-source-plugin-version> + <maven-javadoc-plugin-version>2.10.3</maven-javadoc-plugin-version> + </properties> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>io.dropwizard</groupId> + <artifactId>dropwizard-bom</artifactId> + <version>${dropwizard.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + + <dependencies> + <dependency> + <groupId>io.dropwizard</groupId> + <artifactId>dropwizard-core</artifactId> + </dependency> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + <version>${commons-io.version}</version> + </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + <version>${gson.version}</version> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>${httpclient.version}</version> + </dependency> + <dependency> + <groupId>org.easymock</groupId> + <artifactId>easymock</artifactId> + <version>${easymock.version}</version> + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-module-junit4</artifactId> + <version>${powermock-api-easymock.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-api-easymock</artifactId> + <version>${powermock-api-easymock.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.jacoco</groupId> + <artifactId>jacoco-maven-plugin</artifactId> + <version>${jacoco-maven-plugin.version}</version> + </dependency> + <dependency> + <groupId>io.swagger</groupId> + <artifactId>swagger-jersey2-jaxrs</artifactId> + <version>${swagger-jersey2-jaxrs}</version> + <scope>compile</scope> + <exclusions> + <exclusion> + <groupId>com.google.code.findbugs</groupId> + <artifactId>annotations</artifactId> + </exclusion> + </exclusions> + </dependency> + </dependencies> + + <build> + <finalName>${project.artifactId}</finalName> + <resources> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + </resource> + </resources> + <plugins> + <plugin> + <artifactId>maven-shade-plugin</artifactId> + <version>${maven-shade-plugin.version}</version> + <configuration> + <createDependencyReducedPom>true</createDependencyReducedPom> + <transformers> + <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> + <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> + <mainClass>${mainClass}</mainClass> + </transformer> + </transformers> + <!-- exclude signed Manifests --> + <filters> + <filter> + <artifact>*:*</artifact> + <excludes> + <exclude>META-INF/*.SF</exclude> + <exclude>META-INF/*.DSA</exclude> + <exclude>META-INF/*.RSA</exclude> + </excludes> + </filter> + </filters> + </configuration> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-jar-plugin</artifactId> + <version>${maven-jar-plugin-version}</version> + <configuration> + <archive> + <manifest> + <addClasspath>true</addClasspath> + <mainClass>${mainClass}</mainClass> + </manifest> + </archive> + </configuration> + </plugin> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <version>${maven-compiler-plugin-version}</version> + <configuration> + <source>${java-source-target-version}</source> + <target>${java-source-target-version}</target> + </configuration> + </plugin> + <plugin> + <artifactId>maven-source-plugin</artifactId> + <version>${maven-source-plugin-version}</version> + <executions> + <execution> + <id>attach-sources</id> + <goals> + <goal>jar</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <version>${maven-javadoc-plugin-version}</version> + <executions> + <execution> + <id>attach-javadocs</id> + <goals> + <goal>jar</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>sonar-maven-plugin</artifactId> + <version>${sonar-maven-plugin.version}</version> + </plugin> + <plugin> + <groupId>org.jacoco</groupId> + <artifactId>jacoco-maven-plugin</artifactId> + <version>${jacoco-maven-plugin.version}</version> + <configuration> + <skip>${maven.test.skip}</skip> + <output>file</output> + <append>true</append> + <excludes> + <exclude>**/Globals.*</exclude> + </excludes> + </configuration> + <executions> + <execution> + <id>jacoco-initialize</id> + <goals> + <goal>prepare-agent</goal> + </goals> + </execution> + <execution> + <id>jacoco-site</id> + <phase>verify</phase> + <goals> + <goal>report</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>com.github.kongchen</groupId> + <artifactId>swagger-maven-plugin</artifactId> + <version>${swagger-maven-plugin-version}</version> + <configuration> + <skipSwaggerGeneration>false</skipSwaggerGeneration> + <apiSources> + <apiSource> + <springmvc>false</springmvc> + <locations> + <location>org.eclipse.openk</location> + </locations> + <schemes> + <shema>http</shema> + </schemes> + <host>localhost:9010</host> + <basePath>/mics/central</basePath> + <info> + <title>micsCentralService@openK - Backend REST-Service documentation</title> + <version>v1</version> + <description>This documentation contains the description of all used REST services.</description> + <termsOfService> + . + </termsOfService> + <contact> + <email>nn@pta.de</email> + <name></name> + </contact> + <license> + <url>http://www.apache.org/licenses/LICENSE-2.0.html</url> + <name>Apache 2.0</name> + </license> + </info> + <outputFormats>yaml</outputFormats> + <templatePath>${basedir}/templates/strapdown.html.hbs</templatePath> + <outputPath>target/generated-docs/swaggerInterfaceDocumentation.html</outputPath> + <swaggerDirectory>target/generated-docs</swaggerDirectory> + <securityDefinitions> + <securityDefinition> + <json>/securityDefinitions.json</json> + </securityDefinition> + </securityDefinitions> + </apiSource> + </apiSources> + </configuration> + <executions> + <execution> + <phase>compile</phase> + <goals> + <goal>generate</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + + +</project>
diff --git a/serviceConfigDevLocal.yml b/serviceConfigDevLocal.yml new file mode 100644 index 0000000..eec7e02 --- /dev/null +++ b/serviceConfigDevLocal.yml
@@ -0,0 +1,26 @@ +servicesDistributionFileName: servicesDistributionDevLocal.json +proxyHost: webproxy3.pta.de +proxyPort: 8080 + +logging: + level: INFO + appenders: + - type: file + currentLogFilename: /log/mics-central-service.log + threshold: ALL + archive: true + archivedLogFilenamePattern: /log/mics-central-service-%d.log + archivedFileCount: 5 + timeZone: UTC + loggers: + org.eclipse.openk: DEBUG + org.eclipse.jetty.servlets: DEBUG + +server: + applicationConnectors: + - type: http + port: 9010 + adminConnectors: + - type: http + port: 9011 +
diff --git a/serviceConfigDevLocal_MASTER.yml b/serviceConfigDevLocal_MASTER.yml new file mode 100644 index 0000000..0a83714 --- /dev/null +++ b/serviceConfigDevLocal_MASTER.yml
@@ -0,0 +1,26 @@ +servicesDistributionFileName: servicesDistributionDevServer.json +proxyHost: +proxyPort: + +logging: + level: INFO + appenders: + - type: file + currentLogFilename: /log/mics-central-service.log + threshold: ALL + archive: true + archivedLogFilenamePattern: /log/mics-central-service-%d.log + archivedFileCount: 5 + timeZone: UTC + loggers: + org.eclipse.openk: INFO + org.eclipse.jetty.servlets: DEBUG + +server: + applicationConnectors: + - type: http + port: 9010 + adminConnectors: + - type: http + port: 9011 +
diff --git a/serviceConfigDocker.yml b/serviceConfigDocker.yml new file mode 100644 index 0000000..38ea5bb --- /dev/null +++ b/serviceConfigDocker.yml
@@ -0,0 +1,25 @@ +servicesDistributionFileName: servicesDistributionDocker.json + + +logging: + level: INFO + appenders: + - type: file + currentLogFilename: /log/mics-central-service.log + threshold: ALL + archive: true + archivedLogFilenamePattern: /log/mics-central-service-%d.log + archivedFileCount: 5 + timeZone: UTC + loggers: + org.eclipse.openk: DEBUG + org.eclipse.jetty.servlets: DEBUG + +server: + applicationConnectors: + - type: http + port: 9010 + adminConnectors: + - type: http + port: 9011 +
diff --git a/serviceConfig_QA.yml b/serviceConfig_QA.yml new file mode 100644 index 0000000..e49270f --- /dev/null +++ b/serviceConfig_QA.yml
@@ -0,0 +1,26 @@ +servicesDistributionFileName: servicesDistributionQAServer.json +proxyHost: +proxyPort: + +logging: + level: INFO + appenders: + - type: file + currentLogFilename: /opt/mics/logs/mics-central-service.log + threshold: ALL + archive: true + archivedLogFilenamePattern: /opt/mics/logs/mics-central-service-%d.log + archivedFileCount: 5 + timeZone: UTC + loggers: + org.eclipse.openk: DEBUG + org.eclipse.jetty.servlets: DEBUG + +server: + applicationConnectors: + - type: http + port: 9010 + adminConnectors: + - type: http + port: 9011 +
diff --git a/servicesDistributionDevLocal.json b/servicesDistributionDevLocal.json new file mode 100644 index 0000000..ec1db9b --- /dev/null +++ b/servicesDistributionDevLocal.json
@@ -0,0 +1,77 @@ +[ + { + "active": "true", + "clustername": "elogbook.openK", + "description": "elogbook service cluster for openKonsequenz", + "distributions": [ + { + "active": "true", + "name": "planned-grid-measures.openK", + "protocol": "http", + "host": "localhost", + "urlPath": "/mics/gridmeasures", + "portApp": "9050", + "portHealth": "9051", + "description": "Planned Grid Measures Backend" + }, + { + "active": "true", + "name": "mics-central-service", + "protocol": "http", + "host": "localhost", + "urlPath": "/mics/central", + "portApp": "9010", + "portHealth": "9011", + "description": "Mics Central Service-Configures and dispatches different service clusters for different modules" + } + ] + }, + { + "active": "true", + "clustername": "openK", + "description": "service cluster for openKonsequenz", + "distributions": [ + { + "active": "true", + "name": "planned-grid-measures.openK", + "protocol": "http", + "host": "localhost", + "urlPath": "/mics/gridmeasures", + "portApp": "9050", + "portHealth": "9051", + "description": "Planned Grid Measures Backend" + }, + { + "active": "true", + "name": "authNauth.openK", + "protocol": "http", + "host": "localhost", + "urlPath": "/portal/rest/beservice", + "healthUrlPath": "/portal/rest/beservice", + "portApp": "8080", + "portHealth": "8080", + "description": "Auth&Auth-Modul" + }, + { + "active": "true", + "name": "mics-central-service", + "protocol": "http", + "host": "localhost", + "urlPath": "/mics/central", + "portApp": "9010", + "portHealth": "9011", + "description": "Mics Central Service-Configures and dispatches different service clusters for different modules" + }, + { + "active": "true", + "name": "cim-cache", + "protocol": "https", + "host": "169.50.13.154", + "urlPath": "/domain", + "portApp": "443", + "portHealth": "", + "description": "CIM-Cache Domain API" + } + ] + } +] \ No newline at end of file
diff --git a/servicesDistributionDevServer.json b/servicesDistributionDevServer.json new file mode 100644 index 0000000..af6b818 --- /dev/null +++ b/servicesDistributionDevServer.json
@@ -0,0 +1,77 @@ +[ + { + "active": "true", + "clustername": "elogbook.openK", + "description": "elogbook service cluster for openKonsequenz", + "distributions": [ + { + "active": "true", + "name": "auth-n-auth.mics", + "protocol": "http", + "host": "172.18.22.160", + "urlPath": "/authNAuth", + "portApp": "9002", + "portHealth": "9003", + "description": "Authentication Service" + }, + { + "active": "true", + "name": "mics-central-service", + "protocol": "http", + "host": "172.18.22.160", + "urlPath": "/mics/central", + "portApp": "9010", + "portHealth": "9011", + "description": "Mics Central Service-Configures and dispatches different service clusters for different modules" + } + ] + }, + { + "active": "true", + "clustername": "openK", + "description": "service cluster for openKonsequenz", + "distributions": [ + { + "active": "true", + "name": "planned-grid-measures.openK", + "protocol": "http", + "host": "172.18.22.160", + "urlPath": "/mics/gridmeasures", + "portApp": "9050", + "portHealth": "9051", + "description": "Planned Grid Measures Backend" + }, + { + "active": "true", + "name": "authNauth.openK", + "protocol": "http", + "host": "172.18.22.160", + "urlPath": "/portal/rest/beservice", + "healthUrlPath": "/portal/rest/beservice", + "portApp": "8880", + "portHealth": "8880", + "description": "Auth&Auth-Modul" + }, + { + "active": "true", + "name": "mics-central-service", + "protocol": "http", + "host": "172.18.22.160", + "urlPath": "/mics/central", + "portApp": "9010", + "portHealth": "9011", + "description": "Mics Central Service-Configures and dispatches different service clusters for different modules" + }, + { + "active": "true", + "name": "cim-cache", + "protocol": "https", + "host": "169.50.13.154", + "urlPath": "/domain", + "portApp": "443", + "portHealth": "", + "description": "CIM-Cache Domain API" + } + ] + } +] \ No newline at end of file
diff --git a/servicesDistributionDocker.json b/servicesDistributionDocker.json new file mode 100644 index 0000000..b2afaa4 --- /dev/null +++ b/servicesDistributionDocker.json
@@ -0,0 +1,66 @@ +[ + { + "active": "true", + "clustername": "elogbook.openK", + "description": "elogbook service cluster for openKonsequenz", + "distributions": [ + { + "active": "true", + "name": "planned-grid-measures.openK", + "protocol": "http", + "host": "localhost", + "urlPath": "/mics/gridmeasures", + "portApp": "9050", + "portHealth": "9051", + "description": "Planned Grid Measures Backend" + }, + { + "active": "true", + "name": "mics-central-service", + "protocol": "http", + "host": "localhost", + "urlPath": "/mics/central", + "portApp": "9010", + "portHealth": "9011", + "description": "Mics Central Service-Configures and dispatches different service clusters for different modules" + } + ] + }, + { + "active": "true", + "clustername": "openK", + "description": "service cluster for openKonsequenz", + "distributions": [ + { + "active": "true", + "name": "planned-grid-measures.openK", + "protocol": "http", + "host": "172.25.0.88", + "urlPath": "/mics/gridmeasures", + "portApp": "9050", + "portHealth": "9051", + "description": "Planned Grid Measures Backend" + }, + { + "active": "true", + "name": "mics-central-service", + "protocol": "http", + "host": "localhost", + "urlPath": "/mics/central", + "portApp": "9010", + "portHealth": "9011", + "description": "Mics Central Service-Configures and dispatches different service clusters for different modules" + }, + { + "active": "true", + "name": "cim-cache", + "protocol": "https", + "host": "169.50.13.154", + "urlPath": "/domain", + "portApp": "443", + "portHealth": "", + "description": "CIM-Cache Domain API" + } + ] + } +] \ No newline at end of file
diff --git a/servicesDistributionQAServer.json b/servicesDistributionQAServer.json new file mode 100644 index 0000000..eb650f0 --- /dev/null +++ b/servicesDistributionQAServer.json
@@ -0,0 +1,77 @@ +[ + { + "active": "true", + "clustername": "elogbook.openK", + "description": "elogbook service cluster for openKonsequenz", + "distributions": [ + { + "active": "true", + "name": "auth-n-auth.mics", + "protocol": "http", + "host": "169.50.13.154", + "urlPath": "/authNAuth", + "portApp": "9002", + "portHealth": "9003", + "description": "Authentication Service" + }, + { + "active": "true", + "name": "mics-central-service", + "protocol": "http", + "host": "169.50.13.154", + "urlPath": "/mics/central", + "portApp": "9010", + "portHealth": "9011", + "description": "Mics Central Service-Configures and dispatches different service clusters for different modules" + } + ] + }, + { + "active": "true", + "clustername": "openK", + "description": "service cluster for openKonsequenz", + "distributions": [ + { + "active": "true", + "name": "planned-grid-measures.openK", + "protocol": "http", + "host": "169.50.13.154", + "urlPath": "/mics/gridmeasures", + "portApp": "9050", + "portHealth": "9051", + "description": "Planned Grid Measures Backend" + }, + { + "active": "true", + "name": "authNauth.openK", + "protocol": "http", + "host": "169.50.13.154", + "urlPath": "/portal/rest/beservice", + "healthUrlPath": "/portal/rest/beservice", + "portApp": "8080", + "portHealth": "8080", + "description": "Auth&Auth-Modul" + }, + { + "active": "true", + "name": "mics-central-service", + "protocol": "http", + "host": "169.50.13.154", + "urlPath": "/mics/central", + "portApp": "9010", + "portHealth": "9011", + "description": "Mics Central Service-Configures and dispatches different service clusters for different modules" + }, + { + "active": "true", + "name": "cim-cache", + "protocol": "https", + "host": "169.50.13.154", + "urlPath": "/domain", + "portApp": "443", + "portHealth": "", + "description": "CIM-Cache Domain API" + } + ] + } +] \ No newline at end of file
diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000..09164a6 --- /dev/null +++ b/sonar-project.properties
@@ -0,0 +1,16 @@ +# must be unique in a given SonarQube instance +sonar.projectKey=openk.pta.de:plannedGridMeasures-mics-central-service-BE +# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1. +sonar.projectName=plannedGridMeasures-mics-central-service-BE +sonar.projectVersion=0.0.1_Snapshot + +sonar.sourceEncoding=UTF-8 +sonar.sources=src/main +sonar.language=java +sonar.exclusions=**/common/Globals.java,**/rest/*.java,**/LoggerUtil.java,**/dao/*.java,**/dao/interfaces/*.java,**/controller/BackendController*.java,**/auth2/**/*.java,**/communication/RestServiceWrapper.java,**/controller/BackendController.java +sonar.binaries=target/classes +sonar.cpd.exclusions=**/model/*.java,**/api/*.java +sonar.tests=src/test +sonar.java.coveragePlugin=jacoco +sonar.junit.reportPaths=target/surefire-reports +sonar.jacoco.reportPath=target/jacoco.exec
diff --git a/src/main/java/org/eclipse/openk/MicsCentralApplication.java b/src/main/java/org/eclipse/openk/MicsCentralApplication.java new file mode 100644 index 0000000..e0479a0 --- /dev/null +++ b/src/main/java/org/eclipse/openk/MicsCentralApplication.java
@@ -0,0 +1,85 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk; + +import com.codahale.metrics.health.HealthCheck; +import io.dropwizard.Application; +import io.dropwizard.setup.Bootstrap; +import io.dropwizard.setup.Environment; +import org.eclipse.jetty.servlets.CrossOriginFilter; +import org.eclipse.openk.core.controller.BackendConfig; +import org.eclipse.openk.core.controller.InitServicesConfigCacheJob; +import org.eclipse.openk.health.ConfigFilePresentHealthCheck; +import org.eclipse.openk.resources.MicsCentralResource; + +import javax.servlet.DispatcherType; +import javax.servlet.FilterRegistration; +import java.util.EnumSet; + +public class MicsCentralApplication extends Application<MicsCentralConfiguration> { + + public static void main(final String[] args) throws Exception { + new MicsCentralApplication().run(args); + } + + @Override + public String getName() { + return "micsCentral"; + } + + @Override + public void initialize(final Bootstrap<MicsCentralConfiguration> bootstrap) { + // nothing to do here for now + } + + @Override + public void run(final MicsCentralConfiguration configuration, + final Environment environment) { + + initAppEnvironment( configuration ); + + final MicsCentralResource micsCentralResource = new MicsCentralResource(); + final HealthCheck configFilePresentHC = new ConfigFilePresentHealthCheck(); + + environment.healthChecks().register("configFilePresent", configFilePresentHC ); + environment.jersey().register(micsCentralResource); + + configureCors(environment); + } + + private void initAppEnvironment( MicsCentralConfiguration conf ) { + InitServicesConfigCacheJob.init(conf.getServicesDistributionFileName()); + BackendConfig.getInstance().setProxyHost(conf.getProxyHost()); + BackendConfig.getInstance().setProxyPort( + Integer.parseInt(null != conf.getProxyPort() ? conf.getProxyPort() : "-1")); + } + + private void configureCors(Environment environment) { + final FilterRegistration.Dynamic cors = + environment.servlets().addFilter("CORS", CrossOriginFilter.class); + + // Configure CORS parameters + cors.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*"); + cors.setInitParameter(CrossOriginFilter.TIMING_ALLOW_ORIGIN_HEADER, "*"); + cors.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM, "X-Requested-With,Content-Type,Accept,Origin,Authorization,X-XSRF-TOKEN"); + cors.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "OPTIONS,GET,PUT,POST,DELETE,HEAD"); + cors.setInitParameter(CrossOriginFilter.ALLOW_CREDENTIALS_PARAM, "true"); + + // Add URL mapping + cors.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*"); + // DO NOT pass a preflight request to down-stream auth filters + // unauthenticated preflight requests should be permitted by spec + cors.setInitParameter(CrossOriginFilter.CHAIN_PREFLIGHT_PARAM, Boolean.FALSE.toString()); + } + +}
diff --git a/src/main/java/org/eclipse/openk/MicsCentralConfiguration.java b/src/main/java/org/eclipse/openk/MicsCentralConfiguration.java new file mode 100644 index 0000000..df7c7b0 --- /dev/null +++ b/src/main/java/org/eclipse/openk/MicsCentralConfiguration.java
@@ -0,0 +1,54 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk; + +import io.dropwizard.Configuration; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.hibernate.validator.constraints.*; + +public class MicsCentralConfiguration extends Configuration { + @NotEmpty + private String servicesDistributionFileName; + + @JsonProperty + private String proxyHost; + + @JsonProperty + private String proxyPort; + + @JsonProperty + public String getServicesDistributionFileName() { + return servicesDistributionFileName; + } + + @JsonProperty + public void setServicesDistributionFileName(String servicesDistributionFileName) { + this.servicesDistributionFileName = servicesDistributionFileName; + } + + public String getProxyHost() { + return proxyHost; + } + + public void setProxyHost(String proxyHost) { + this.proxyHost = proxyHost; + } + + public String getProxyPort() { + return proxyPort; + } + + public void setProxyPort(String proxyPort) { + this.proxyPort = proxyPort; + } +}
diff --git a/src/main/java/org/eclipse/openk/api/ServiceDistributionCluster.java b/src/main/java/org/eclipse/openk/api/ServiceDistributionCluster.java new file mode 100644 index 0000000..5c5bc8b --- /dev/null +++ b/src/main/java/org/eclipse/openk/api/ServiceDistributionCluster.java
@@ -0,0 +1,185 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.api; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.hibernate.validator.constraints.NotEmpty; + + +public class ServiceDistributionCluster { + + public static class ServiceDistribution { + + private boolean active; + + @NotEmpty + private String name; + + @NotEmpty + private String host; + + @NotEmpty + private String urlPath; + + private String healthUrlPath; + + @NotEmpty + private String protocol; + + @NotEmpty + private Integer portApp; + + private Integer portHealth; + + private String description; + + public ServiceDistribution() { + // public default construction + } + + @JsonProperty + public boolean isActive() { + return active; + } + + @JsonProperty + public void setActive(boolean active) { + this.active = active; + } + + @JsonProperty + public String getName() { + return name; + } + + @JsonProperty + public void setName(String name) { + this.name = name; + } + + @JsonProperty + public String getHost() { + return host; + } + + @JsonProperty + public void setHost(String host) { + this.host = host; + } + + @JsonProperty + public String getUrlPath() { + return urlPath; + } + + @JsonProperty + public void setUrlPath(String urlPath) { + this.urlPath = urlPath; + } + + public String getHealthUrlPath() { + return healthUrlPath; + } + + public void setHealthUrlPath(String healthUrlPath) { + this.healthUrlPath = healthUrlPath; + } + + @JsonProperty + public String getProtocol() { + return protocol; + } + + @JsonProperty + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + @JsonProperty + public int getPortApp() { + return portApp; + } + + @JsonProperty + public void setPortApp(int portApp) { + this.portApp = portApp; + } + + @JsonProperty + public String getDescription() { + return description; + } + + @JsonProperty + public void setDescription(String description) { + this.description = description; + } + + @JsonProperty + public Integer getPortHealth() { + return portHealth; + } + + @JsonProperty + public void setPortHealth(Integer portHealth) { + this.portHealth = portHealth; + } + } + + private boolean active; + + @NotEmpty + private String clustername; + + private String description; + + private ServiceDistribution[] distributions; + + @JsonProperty + public boolean isActive() { + return active; + } + + @JsonProperty + public void setActive(boolean active) { + this.active = active; + } + + @JsonProperty + public String getClustername() { + return clustername; + } + + @JsonProperty + public void setClustername(String clustername) { + this.clustername = clustername; + } + + @JsonProperty + public String getDescription() { + return description; + } + + @JsonProperty + public void setDescription(String description) { + this.description = description; + } + + public ServiceDistribution[] getDistributions() { + return distributions; + } + + public void setDistributions(ServiceDistribution[] distributions) { + this.distributions = distributions; + } +}
diff --git a/src/main/java/org/eclipse/openk/api/ServiceRequestEnvelope.java b/src/main/java/org/eclipse/openk/api/ServiceRequestEnvelope.java new file mode 100644 index 0000000..61abca8 --- /dev/null +++ b/src/main/java/org/eclipse/openk/api/ServiceRequestEnvelope.java
@@ -0,0 +1,118 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.api; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.log4j.Logger; +import org.glassfish.jersey.internal.util.Base64; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; + +public class ServiceRequestEnvelope { + private static final Logger logger = Logger.getLogger(ServiceRequestEnvelope.class); + public static class HttpHeader { + private String attribute; + private String value; + + public String getAttribute() { + return attribute; + } + + public void setAttribute(String attribute) { + this.attribute = attribute; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + private String serviceName; + private String method; + private String uriFragment; + private String payload; + private HttpHeader[] headers; + + @JsonProperty + public String getServiceName() { + return serviceName; + } + + @JsonProperty + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + @JsonProperty + public String getMethod() { + return method; + } + + @JsonProperty + public void setMethod(String method) { + this.method = method; + } + + @JsonProperty + public String getUriFragment() { + return uriFragment; + } + + @JsonProperty + public void setUriFragment(String uriFragment) { + this.uriFragment = uriFragment; + } + + @JsonProperty + public String getPayload() { + return payload; + } + + @JsonProperty + public void setPayload(String payload) { + this.payload = payload; + } + + @JsonProperty + public HttpHeader[] getHeaders() { + return headers; + } + + @JsonProperty + public void setHeaders(HttpHeader[] headers) { + this.headers = headers; + } + + public String getPayloadDecode() { + if( payload != null && !payload.isEmpty()) { + try { + return URLDecoder.decode(Base64.decodeAsString(payload), "UTF-8"); + } catch (UnsupportedEncodingException e) { + logger.error("Unsupported Encoding", e); + return ""; + } + } + else { + return ""; + } + } + + public void setPayloadEncode(String payload) { + this.payload = Base64.encodeAsString(payload); + } +}
diff --git a/src/main/java/org/eclipse/openk/api/VersionInfo.java b/src/main/java/org/eclipse/openk/api/VersionInfo.java new file mode 100644 index 0000000..a5bc079 --- /dev/null +++ b/src/main/java/org/eclipse/openk/api/VersionInfo.java
@@ -0,0 +1,27 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.api; + +public class VersionInfo { + private String backendVersion; + + public String getBackendVersion() { + return backendVersion; + } + + public void setBackendVersion(String backendVersion) { + this.backendVersion = backendVersion; + } + + +}
diff --git a/src/main/java/org/eclipse/openk/core/common/Globals.java b/src/main/java/org/eclipse/openk/core/common/Globals.java new file mode 100644 index 0000000..0331396 --- /dev/null +++ b/src/main/java/org/eclipse/openk/core/common/Globals.java
@@ -0,0 +1,22 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.common; + + +public final class Globals { + public static final String HEADER_JSON_UTF8 = "application/json; charset=utf-8"; + public static final String HEALTH_CHECK_ADD_PATH = "healthcheck?pretty=true"; + + private Globals() { + } +}
diff --git a/src/main/java/org/eclipse/openk/core/common/GsonUTCDateAdapter.java b/src/main/java/org/eclipse/openk/core/common/GsonUTCDateAdapter.java new file mode 100644 index 0000000..e284869 --- /dev/null +++ b/src/main/java/org/eclipse/openk/core/common/GsonUTCDateAdapter.java
@@ -0,0 +1,47 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.common; + +import com.google.gson.*; + +import java.lang.reflect.Type; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +public class GsonUTCDateAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> { + + private final DateFormat dateFormat; + + public GsonUTCDateAdapter() { + dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US); //This is the format I need + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); //This is the key line which converts the date to UTC which cannot be accessed with the default serializer + } + + @Override + public synchronized JsonElement serialize(Date date, Type type, JsonSerializationContext jsonSerializationContext) { + return new JsonPrimitive(dateFormat.format(date)); + } + + @Override + public synchronized Date deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) { + try { + return dateFormat.parse(jsonElement.getAsString()); + } catch (ParseException e) { + throw new JsonParseException(e); + } + } +} \ No newline at end of file
diff --git a/src/main/java/org/eclipse/openk/core/common/JsonGeneratorBase.java b/src/main/java/org/eclipse/openk/core/common/JsonGeneratorBase.java new file mode 100644 index 0000000..5f1a734 --- /dev/null +++ b/src/main/java/org/eclipse/openk/core/common/JsonGeneratorBase.java
@@ -0,0 +1,28 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.common; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.util.Date; + +public class JsonGeneratorBase { + private JsonGeneratorBase() {} + public static Gson getGson() { + return new GsonBuilder() + .registerTypeAdapter(Date.class, new GsonUTCDateAdapter()) + .disableHtmlEscaping() + .create(); + } +}
diff --git a/src/main/java/org/eclipse/openk/core/common/util/ResourceLoaderBase.java b/src/main/java/org/eclipse/openk/core/common/util/ResourceLoaderBase.java new file mode 100644 index 0000000..0619003 --- /dev/null +++ b/src/main/java/org/eclipse/openk/core/common/util/ResourceLoaderBase.java
@@ -0,0 +1,38 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.common.util; + +import org.apache.commons.io.IOUtils; + +import java.io.InputStream; +import java.io.StringWriter; + +public class ResourceLoaderBase { + private String stream2String(InputStream is) { + StringWriter writer = new StringWriter(); + try { + IOUtils.copy(is, writer, "UTF-8"); + } catch (Exception e) { // NOSONAR + return ""; + } + return writer.toString(); + + + } + + public String loadStringFromResource(String filename) { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + InputStream jsonstream = classLoader.getResourceAsStream(filename); + return stream2String(jsonstream); + } +}
diff --git a/src/main/java/org/eclipse/openk/core/communication/RestServiceWrapper.java b/src/main/java/org/eclipse/openk/core/communication/RestServiceWrapper.java new file mode 100644 index 0000000..1a16b9a --- /dev/null +++ b/src/main/java/org/eclipse/openk/core/communication/RestServiceWrapper.java
@@ -0,0 +1,221 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.communication; + + +import org.apache.commons.httpclient.HostConfiguration; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.*; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.util.EntityUtils; +import org.apache.log4j.Logger; +import org.eclipse.openk.core.common.Globals; +import org.eclipse.openk.core.controller.BackendConfig; +import org.eclipse.openk.core.exceptions.HttpStatusException; + +import javax.ws.rs.core.Response; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.List; + +public class RestServiceWrapper { + public static class HttpHeader { + private String attribute; + private String value; + + public HttpHeader(String attribute, String value) { + this.attribute = attribute; + this.value = value; + } + + public String getAttribute() { + return attribute; + } + + public void setAttribute(String attribute) { + this.attribute = attribute; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + private static final Logger LOGGER = Logger.getLogger(RestServiceWrapper.class.getName()); + private boolean useHttps; + + public enum HttpMethod {GET, POST, PUT, DELETE} + + public RestServiceWrapper(boolean https) { + this.useHttps = https; + } + + public static HttpHeader createHeader(String attribute, String value) { + return new HttpHeader(attribute, value); + } + + public String performGetRequest(String restFunctionWithParams) throws HttpStatusException { + LOGGER.debug("CompleteUrl: " + restFunctionWithParams); + // create HTTP Client + CloseableHttpClient httpClient = createHttpsClient(); + + // create new Request with given URL + HttpGet getRequest = new HttpGet(restFunctionWithParams); + getRequest.addHeader("accept", Globals.HEADER_JSON_UTF8); + + HttpResponse response; + // Execute request an catch response + try { + response = httpClient.execute(getRequest); + + } catch (IOException e) { + String errtext = "Get communication to <" + restFunctionWithParams + "> failed."; + LOGGER.warn(errtext, e); + throw new HttpStatusException(HttpStatus.SC_SERVICE_UNAVAILABLE); + } + + return createJson(response); + } + + public String performPostRequest(String restFunctionWithParams, String data) throws HttpStatusException { + + // create HTTP Client + CloseableHttpClient httpClient = createHttpsClient(); + + // create new Post Request with given URL + HttpPost postRequest = new HttpPost(restFunctionWithParams); + + // add additional header to getRequest which accepts application/JSON data + postRequest.addHeader("accept", Globals.HEADER_JSON_UTF8); + postRequest.addHeader("Content-Type", Globals.HEADER_JSON_UTF8); + + postRequest.setEntity(new StringEntity(data, StandardCharsets.UTF_8)); + + HttpResponse response; + // Execute request an catch response + try { + response = httpClient.execute(postRequest); + } catch (IOException e) { + String errtext = "Post communication to <" + restFunctionWithParams + "> failed!"; + LOGGER.warn(errtext, e); + throw new HttpStatusException(HttpStatus.SC_SERVICE_UNAVAILABLE); + } + return createJson(response); + } + + public Response performHttpRequest(HttpMethod method, String restFunctionWithParams, + List<HttpHeader> headerList, String data) throws HttpStatusException { + + // create HTTP Client + try (CloseableHttpClient httpClient = createHttpsClient() ) { + + HttpRequestBase request = createRequest(method, restFunctionWithParams, data); + for (HttpHeader header : headerList) { + request.addHeader(header.attribute, header.value); + } + + HttpResponse response; + // Execute request an catch response + response = httpClient.execute(request); + + + String ent = createJson(response); + + Response.ResponseBuilder rb = Response.status(response.getStatusLine().getStatusCode()); + if (ent != null) { + rb.entity(ent); + } + return rb.build(); + } catch (IOException e) { + String errtext = "Communication to <" + restFunctionWithParams + "> failed..."; + LOGGER.warn(errtext, e); + throw new HttpStatusException(HttpStatus.SC_SERVICE_UNAVAILABLE); + } + } + + private HttpRequestBase createRequest(HttpMethod method, String restFunctionWithParams, String data) throws HttpStatusException { + HttpRequestBase ret; + switch (method) { + case GET: + ret = new HttpGet(restFunctionWithParams); + break; + case POST: + ret = setPayload(new HttpPost(restFunctionWithParams), data); + break; + case PUT: + ret = setPayload(new HttpPut(restFunctionWithParams), data); + break; + case DELETE: + ret = new HttpDelete(restFunctionWithParams); + break; + default: + throw new HttpStatusException(HttpStatus.SC_METHOD_NOT_ALLOWED); + } + return ret; + } + + private HttpRequestBase setPayload(HttpEntityEnclosingRequestBase req, String data) { + req.setEntity(new StringEntity(data, StandardCharsets.UTF_8)); + return req; + } + + + private CloseableHttpClient createHttpsClient() throws HttpStatusException { + if (useHttps) { + try { + SSLContextBuilder builder = new SSLContextBuilder(); + builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); + SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(), new NoopHostnameVerifier()); + + String proxyHost = BackendConfig.getInstance().getProxyHost(); + int proxyPort = BackendConfig.getInstance().getProxyPort(); + if (proxyHost != null && !proxyHost.isEmpty()){ + return HttpClients.custom().setSSLSocketFactory(sslsf).setProxy(new HttpHost(proxyHost, proxyPort)).build(); + } + + return HttpClients.custom().setSSLSocketFactory(sslsf).build(); + } catch (Exception e) { + LOGGER.error(e); + throw new HttpStatusException(HttpStatus.SC_INTERNAL_SERVER_ERROR); + } + } else { + return HttpClientBuilder.create().build(); + } + } + + private String createJson(HttpResponse response) throws HttpStatusException { + String retJson; + try { + retJson = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); + } catch (IOException e) { + LOGGER.error(e); + throw new HttpStatusException(HttpStatus.SC_INTERNAL_SERVER_ERROR); + } + + return retJson; + } + +}
diff --git a/src/main/java/org/eclipse/openk/core/controller/BackendConfig.java b/src/main/java/org/eclipse/openk/core/controller/BackendConfig.java new file mode 100644 index 0000000..1af2080 --- /dev/null +++ b/src/main/java/org/eclipse/openk/core/controller/BackendConfig.java
@@ -0,0 +1,31 @@ +package org.eclipse.openk.core.controller; + +public class BackendConfig { + + static final private BackendConfig instance = new BackendConfig(); + + private String proxyHost; + private int proxyPort; + + private BackendConfig(){} + + public static BackendConfig getInstance(){ + return instance; + } + + public String getProxyHost() { + return proxyHost; + } + + public void setProxyHost(String proxyHost) { + this.proxyHost = proxyHost; + } + + public int getProxyPort() { + return proxyPort; + } + + public void setProxyPort(int proxyPort) { + this.proxyPort = proxyPort; + } +}
diff --git a/src/main/java/org/eclipse/openk/core/controller/BaseWebService.java b/src/main/java/org/eclipse/openk/core/controller/BaseWebService.java new file mode 100644 index 0000000..1d321f7 --- /dev/null +++ b/src/main/java/org/eclipse/openk/core/controller/BaseWebService.java
@@ -0,0 +1,70 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.controller; + +import org.apache.log4j.Logger; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.openk.core.exceptions.HttpStatusException; + +import javax.ws.rs.core.Response; +import java.io.IOException; +import java.util.Properties; + +public class BaseWebService { + @FunctionalInterface + public interface Invokable <T> { + public T invoke() throws Exception; // NOSONAR + } + private final Logger logger; + + protected BaseWebService(Logger logger) { + this.logger = logger; + } + + protected Response invokeRunnable(Invokable runnable) + { + try { // NOSONAR + Object o = runnable.invoke(); + return Response.ok(o).build(); + } catch (HttpStatusException hse) { + logger.error(hse); + return Response.status(hse.getHttpStatus()).build(); + } + catch (Exception e) { + logger.error("Caught unexpected Exception:", e); + return Response.status(HttpStatus.INTERNAL_SERVER_ERROR_500).build(); + } + } + + + protected String getVersionString() { + try { + // determine static VersionInfo + final Properties properties = new Properties(); + + properties.load(BaseWebService.class.getClassLoader().getResourceAsStream("project.properties")); + + String beversion = properties.getProperty("backend.version"); + if( beversion.contains("$")) { + beversion = "LOCAL-DEV"; + } + return beversion; + } catch (IOException e) { + logger.error("Exception reading the properties file", e); + throw new RuntimeException("Exception during start up"); // NOSONAR + } + } + + + +}
diff --git a/src/main/java/org/eclipse/openk/core/controller/CentralController.java b/src/main/java/org/eclipse/openk/core/controller/CentralController.java new file mode 100644 index 0000000..7a48009 --- /dev/null +++ b/src/main/java/org/eclipse/openk/core/controller/CentralController.java
@@ -0,0 +1,109 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.controller; + +import org.apache.log4j.Logger; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.openk.api.VersionInfo; +import org.eclipse.openk.api.ServiceDistributionCluster; +import org.eclipse.openk.core.common.Globals; +import org.eclipse.openk.core.communication.RestServiceWrapper; +import org.eclipse.openk.core.exceptions.HttpStatusException; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public class CentralController { + private static final Logger logger = Logger.getLogger(CentralController.class); + + public ServiceDistributionCluster readServerDistribution(String cluster) throws HttpStatusException { + ServiceDistributionCluster[] dcs = ServicesConfigCache.getInstance().getCache(); + + for (ServiceDistributionCluster item : dcs) { + if (item.getClustername().equalsIgnoreCase(cluster) && item.isActive()) { + return removeInactiveItems(item); + } + } + logger.error("There is no cluster name equals with " + cluster + " or the cluster is not active."); + throw new HttpStatusException(HttpStatus.NOT_FOUND_404); + } + + public VersionInfo getVersionInfo(String version ) { + VersionInfo vi = new VersionInfo(); + vi.setBackendVersion( version ); + return vi; + } + + + protected RestServiceWrapper createRestServiceWrapper( boolean isHttps ) { + return new RestServiceWrapper(isHttps); + } + + public String getServiceHealthState(String clustername, String servicename) throws HttpStatusException { + + ServiceDistributionCluster.ServiceDistribution dist = findDistribution(clustername, servicename); + RestServiceWrapper w = createRestServiceWrapper(false ); + StringBuilder url = new StringBuilder(); + url.append(dist.getProtocol() + "://" + dist.getHost() + ":" + + dist.getPortHealth()); + + if( dist.getHealthUrlPath() != null ) { + url.append(dist.getUrlPath()); + } + url.append("/" + Globals.HEALTH_CHECK_ADD_PATH ); + + return w.performGetRequest(url.toString()); + } + + private ServiceDistributionCluster.ServiceDistribution findDistribution(String clustername, + String servicename) throws HttpStatusException { + ServiceDistributionCluster cluster = getCluster(ServicesConfigCache.getInstance().getCache(), clustername); + + Optional<ServiceDistributionCluster.ServiceDistribution> dist = Arrays.stream(cluster.getDistributions()) + .filter(e -> e.isActive() && e.getName().equals(servicename)) + .findFirst(); + + if(dist.isPresent()) { + return dist.get(); + } + else { + throw new HttpStatusException(HttpStatus.NOT_FOUND_404); + } + } + + private ServiceDistributionCluster getCluster(ServiceDistributionCluster[] clusterArray, String clustername) throws HttpStatusException { + List<ServiceDistributionCluster> clusterList = Arrays.asList(clusterArray); + Optional<ServiceDistributionCluster> ret = clusterList.stream() + .filter(c -> c.getClustername().equals(clustername)).findFirst(); + + if (ret.isPresent()) { + return ret.get(); + } else { + logger.info("Could not find a cluster with the name: " + clustername); + throw new HttpStatusException(HttpStatus.NOT_FOUND_404); + } + } + + private ServiceDistributionCluster removeInactiveItems( ServiceDistributionCluster cluster ) { + List<ServiceDistributionCluster.ServiceDistribution> dlist = Arrays.asList(cluster.getDistributions()); + dlist = dlist.stream().filter(ServiceDistributionCluster.ServiceDistribution::isActive).collect(Collectors.toList()); + ServiceDistributionCluster.ServiceDistribution[] distArr + = new ServiceDistributionCluster.ServiceDistribution[dlist.size()]; + cluster.setDistributions(dlist.toArray(distArr)); + return cluster; + } + + +}
diff --git a/src/main/java/org/eclipse/openk/core/controller/DispatchController.java b/src/main/java/org/eclipse/openk/core/controller/DispatchController.java new file mode 100644 index 0000000..68125bb --- /dev/null +++ b/src/main/java/org/eclipse/openk/core/controller/DispatchController.java
@@ -0,0 +1,77 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.controller; + +import com.google.common.collect.Lists; +import org.apache.log4j.Logger; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.openk.api.ServiceDistributionCluster; +import org.eclipse.openk.api.ServiceDistributionCluster.ServiceDistribution; +import org.eclipse.openk.api.ServiceRequestEnvelope; +import org.eclipse.openk.core.communication.RestServiceWrapper; +import org.eclipse.openk.core.exceptions.HttpStatusException; + +import javax.ws.rs.core.Response; +import java.util.List; + +import static java.util.stream.Collectors.toList; + +public class DispatchController { + private static Logger logger = Logger.getLogger(DispatchController.class); + + public Response dispatch(String clustername, ServiceRequestEnvelope envelope) throws HttpStatusException { + + List<RestServiceWrapper.HttpHeader> transformedList = Lists.newArrayList(envelope.getHeaders()).stream() + .map(header -> + RestServiceWrapper.createHeader(header.getAttribute(), header.getValue())).collect(toList()); + + String url = locateBaseUrl(ServicesConfigCache.getInstance().getCache(), + clustername, envelope.getServiceName()) + + envelope.getUriFragment(); + + RestServiceWrapper rsWrap = createRestServiceWrapper(url.toUpperCase().startsWith("HTTPS")); + return rsWrap.performHttpRequest(resolveMethod(envelope.getMethod()), + url, transformedList, envelope.getPayloadDecode()); + } + + protected RestServiceWrapper createRestServiceWrapper(boolean useHttps) { + return new RestServiceWrapper(useHttps); + } + + private String locateBaseUrl(ServiceDistributionCluster[] cluster, String clustername, String servicename) throws HttpStatusException { + ServiceDistribution dist = new ServiceResolver(cluster) + .resolve(clustername, servicename); + if (dist == null) { + logger.error("Service [" + clustername + "]/[" + servicename + "] is not resolvable!"); + throw new HttpStatusException(HttpStatus.NOT_FOUND_404); + } + return dist.getProtocol() + "://" + dist.getHost() + ":" + dist.getPortApp() + dist.getUrlPath(); + } + + private RestServiceWrapper.HttpMethod resolveMethod(String method) throws HttpStatusException { + switch (method.toUpperCase()) { + case "GET": + return RestServiceWrapper.HttpMethod.GET; + case "POST": + return RestServiceWrapper.HttpMethod.POST; + case "PUT": + return RestServiceWrapper.HttpMethod.PUT; + case "DELETE": + return RestServiceWrapper.HttpMethod.DELETE; + default: + logger.error("Invalid Method: " + method); + throw new HttpStatusException(HttpStatus.METHOD_NOT_ALLOWED_405); + } + + } +}
diff --git a/src/main/java/org/eclipse/openk/core/controller/InitServicesConfigCacheJob.java b/src/main/java/org/eclipse/openk/core/controller/InitServicesConfigCacheJob.java new file mode 100644 index 0000000..41642d0 --- /dev/null +++ b/src/main/java/org/eclipse/openk/core/controller/InitServicesConfigCacheJob.java
@@ -0,0 +1,33 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.controller; + +import org.apache.log4j.Logger; + +import java.util.Timer; +import java.util.TimerTask; + +public class InitServicesConfigCacheJob { + + private static final Logger LOGGER = Logger.getLogger(InitServicesConfigCacheJob.class.getName()); + + private InitServicesConfigCacheJob() { + } + + public static void init( String configFileName ) { + LOGGER.info("InitServicesConfigCacheJob called"); + TimerTask timerTask = new ServicesConfigCacheTimerTask(configFileName); + Timer timer = new Timer(); + timer.scheduleAtFixedRate(timerTask, 100, 5000L); + } +}
diff --git a/src/main/java/org/eclipse/openk/core/controller/ServiceResolver.java b/src/main/java/org/eclipse/openk/core/controller/ServiceResolver.java new file mode 100644 index 0000000..fe6e12c --- /dev/null +++ b/src/main/java/org/eclipse/openk/core/controller/ServiceResolver.java
@@ -0,0 +1,43 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.controller; + +import org.eclipse.openk.api.ServiceDistributionCluster; +import org.eclipse.openk.api.ServiceDistributionCluster.ServiceDistribution; + +import java.util.Arrays; +import java.util.Optional; + +public class ServiceResolver { + private final ServiceDistributionCluster[] clusters; + + public ServiceResolver(ServiceDistributionCluster[] clusters) { + this.clusters = clusters; + } + + public ServiceDistribution resolve(String clustername, String servicename) { + Optional<ServiceDistributionCluster> cluster + = Arrays.stream(clusters).filter( + x -> x.getClustername().equalsIgnoreCase(clustername)).findFirst(); + if (cluster.isPresent()) { + Optional<ServiceDistributionCluster.ServiceDistribution> dist = + Arrays.stream(cluster.get().getDistributions()) + .filter(x -> x.getName().equalsIgnoreCase(servicename)) + .findFirst(); + if (dist.isPresent()) { + return dist.get(); + } + } + return null; + } +}
diff --git a/src/main/java/org/eclipse/openk/core/controller/ServicesConfigCache.java b/src/main/java/org/eclipse/openk/core/controller/ServicesConfigCache.java new file mode 100644 index 0000000..ea276d7 --- /dev/null +++ b/src/main/java/org/eclipse/openk/core/controller/ServicesConfigCache.java
@@ -0,0 +1,89 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.log4j.Logger; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.openk.api.ServiceDistributionCluster; +import org.eclipse.openk.core.exceptions.HttpStatusException; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Set; + +public class ServicesConfigCache { + private static final Logger logger = Logger.getLogger(ServicesConfigCache.class.getName()); + private static ServicesConfigCache instance = new ServicesConfigCache(); + private static final Object lock = new Object(); + + private ServiceDistributionCluster[] cache; + + private ServicesConfigCache(){ + } + + public static ServicesConfigCache getInstance() { + return instance; + } + + + public void readServerDistribution(String configFileName) throws HttpStatusException { + try { + ServiceDistributionCluster[] dcs = readServerDistributionFromText(new String(Files.readAllBytes(Paths.get(configFileName)), Charset.forName("UTF-8"))); + synchronized( lock ) { + cache = dcs; + } + + } catch (IOException e) { + logger.error("Could not read file "+configFileName+"!", e); + throw new HttpStatusException(HttpStatus.INTERNAL_SERVER_ERROR_500); + } + } + + private ServiceDistributionCluster[] readServerDistributionFromText(String jsonText) throws HttpStatusException { + ServiceDistributionCluster[] dcs; + + try { + final ObjectMapper mapper = new ObjectMapper(); + dcs = mapper.readValue(jsonText, ServiceDistributionCluster[].class); + } catch (IOException e) { + logger.error("Could not parse file!", e); + throw new HttpStatusException(HttpStatus.INTERNAL_SERVER_ERROR_500); + } + + ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + Validator validator = factory.getValidator(); + + for (ServiceDistributionCluster item : dcs) { + Set<ConstraintViolation<ServiceDistributionCluster>> violations + = validator.validate(item); + if (!violations.isEmpty()) { + logger.error("Error in configfile!: "); + throw new HttpStatusException(HttpStatus.INTERNAL_SERVER_ERROR_500); + } + } + return dcs; + } + + public ServiceDistributionCluster[] getCache() { + synchronized( lock ) { + return cache; + } + } +}
diff --git a/src/main/java/org/eclipse/openk/core/controller/ServicesConfigCacheTimerTask.java b/src/main/java/org/eclipse/openk/core/controller/ServicesConfigCacheTimerTask.java new file mode 100644 index 0000000..136a26f --- /dev/null +++ b/src/main/java/org/eclipse/openk/core/controller/ServicesConfigCacheTimerTask.java
@@ -0,0 +1,37 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.controller; + +import org.apache.log4j.Logger; +import org.eclipse.openk.core.exceptions.HttpStatusException; + +import java.util.TimerTask; + +public class ServicesConfigCacheTimerTask extends TimerTask { + private static final Logger logger = Logger.getLogger(ServicesConfigCacheTimerTask.class.getName()); + private String configFileName; + + public ServicesConfigCacheTimerTask( String configFileName ) { + this.configFileName = configFileName; + } + + + @Override + public void run() { + try { + ServicesConfigCache.getInstance().readServerDistribution(this.configFileName); + } catch (HttpStatusException e) { + logger.error("Error reading ServerDistributionFile", e); + } + } +}
diff --git a/src/main/java/org/eclipse/openk/core/exceptions/HttpStatusException.java b/src/main/java/org/eclipse/openk/core/exceptions/HttpStatusException.java new file mode 100644 index 0000000..f9348b7 --- /dev/null +++ b/src/main/java/org/eclipse/openk/core/exceptions/HttpStatusException.java
@@ -0,0 +1,25 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.exceptions; + +public class HttpStatusException extends Exception { + private final int httpStatus; + + public HttpStatusException(int httpStatus ) { + this.httpStatus = httpStatus; + } + + public int getHttpStatus() { + return httpStatus; + } +}
diff --git a/src/main/java/org/eclipse/openk/health/ConfigFilePresentHealthCheck.java b/src/main/java/org/eclipse/openk/health/ConfigFilePresentHealthCheck.java new file mode 100644 index 0000000..924d1e7 --- /dev/null +++ b/src/main/java/org/eclipse/openk/health/ConfigFilePresentHealthCheck.java
@@ -0,0 +1,31 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.health; + +import com.codahale.metrics.health.HealthCheck; +import org.eclipse.openk.api.ServiceDistributionCluster; +import org.eclipse.openk.core.controller.ServicesConfigCache; + +public class ConfigFilePresentHealthCheck extends HealthCheck { + @Override + protected Result check() throws Exception { + ServiceDistributionCluster[] sdc = ServicesConfigCache.getInstance().getCache(); // Throws Exception if it fails + + if (sdc != null && sdc.length > 0) { + return Result.healthy(); + } + else { + return Result.unhealthy("No ServiceDistributionCluster available!"); + } + } +}
diff --git a/src/main/java/org/eclipse/openk/resources/MicsCentralResource.java b/src/main/java/org/eclipse/openk/resources/MicsCentralResource.java new file mode 100644 index 0000000..61e62a1 --- /dev/null +++ b/src/main/java/org/eclipse/openk/resources/MicsCentralResource.java
@@ -0,0 +1,96 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.resources; + + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import org.apache.log4j.Logger; +import org.eclipse.openk.api.VersionInfo; +import org.eclipse.openk.core.common.JsonGeneratorBase; +import org.eclipse.openk.core.controller.DispatchController; +import org.hibernate.validator.constraints.NotEmpty; +import org.eclipse.openk.api.ServiceRequestEnvelope; +import org.eclipse.openk.core.controller.CentralController; +import org.eclipse.openk.core.controller.BaseWebService; +import org.eclipse.openk.core.exceptions.HttpStatusException; + +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +@Api(value = "/mics/gridmeasures") +@ApiResponses( value ={ + @ApiResponse(code = 200, message = "OK",response = VersionInfo.class,reference = "#/definitions/VersionInfo"), + @ApiResponse(code = 400, message = "Bad Request"), + @ApiResponse(code = 401, message = "Unauthorized"), + @ApiResponse(code = 404, message = "Not found"), + @ApiResponse(code = 423, message = "Locked"), + @ApiResponse(code = 500, message = "Internal Server Error") } ) +@Path("/mics/central") +@Produces(MediaType.APPLICATION_JSON) +public class MicsCentralResource extends BaseWebService{ + private static Logger logger = Logger.getLogger(MicsCentralResource.class.getName()); + + public MicsCentralResource() { + super(logger); + } + + @ApiOperation(value = "Service Distribution", notes = "This service returns the available distributions for a given cluster") + @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK") } ) + @GET + @Path("/serviceDistribution/{clustername}") + public Response getServiceDistribution(@ApiParam(name = "clustername", value = "The name of the cluster") + @PathParam("clustername") @NotEmpty String clustername) { + return invokeRunnable(() -> new CentralController().readServerDistribution(clustername)); + } + + @ApiOperation(value = "Health state check", notes = "This service checks if the components of a service are healthy") + @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK") } ) + @GET + @Path("/serviceHealthState/{clustername}/{servicename}") + public Response getClusterHealthState(@ApiParam(name = "clustername", value = "The name of the cluster") + @PathParam("clustername") @NotEmpty String clustername, + @ApiParam(name = "servicename", value = "The name of the service") + @PathParam("servicename") @NotEmpty String servicename) { + return invokeRunnable(() -> new CentralController().getServiceHealthState(clustername, servicename)); + } + + @ApiOperation(value = "Dispatcher", notes = "") + @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK") } ) + @POST + @Path("/dispatch/{clustername}") + public Response dispatch(String envelope, + @ApiParam(name = "clustername", value = "The name of the cluster") + @PathParam("clustername") @NotEmpty String clustername) { + ServiceRequestEnvelope envObj = JsonGeneratorBase.getGson().fromJson(envelope, ServiceRequestEnvelope.class); + + try { + return new DispatchController().dispatch(clustername, envObj); + } catch (HttpStatusException hse) { + logger.error(hse); + return Response.status(hse.getHttpStatus()).build(); + } + } + + @ApiOperation(value = "Version Information", notes = "This services displays the version infos of this backend and the connected database.") + @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = VersionInfo.class,reference = "#/definitions/VersionInfo") } ) + @GET + @Path("/versionInfo") + public Response getVersionInfo() { + return invokeRunnable(() -> new CentralController().getVersionInfo(getVersionString())); + } +}
diff --git a/src/main/resources/banner.txt b/src/main/resources/banner.txt new file mode 100644 index 0000000..561b172 --- /dev/null +++ b/src/main/resources/banner.txt
@@ -0,0 +1,6 @@ +================================================================================ + + micsCentral + +================================================================================ +
diff --git a/src/main/resources/project.properties b/src/main/resources/project.properties new file mode 100644 index 0000000..25e06ec --- /dev/null +++ b/src/main/resources/project.properties
@@ -0,0 +1 @@ +backend.version =${project.version} \ No newline at end of file
diff --git a/src/main/resources/securityDefinitions.json b/src/main/resources/securityDefinitions.json new file mode 100644 index 0000000..7183dfd --- /dev/null +++ b/src/main/resources/securityDefinitions.json
@@ -0,0 +1,16 @@ +{ + "api_key": { + "type": "apiKey", + "name": "api_key", + "in": "header" + }, + "Existing JWT token": { + "type": "oauth2", + "authorizationUrl": "http://swagger.io/api/oauth/dialog", + "flow": "implicit", + "scopes": { + "scope1": "scope description 1", + "scope2": "scope description 2" + } + } +} \ No newline at end of file
diff --git a/src/test/java/org/eclipse/openk/MicsCentralApplicationTest.java b/src/test/java/org/eclipse/openk/MicsCentralApplicationTest.java new file mode 100644 index 0000000..a8acd29 --- /dev/null +++ b/src/test/java/org/eclipse/openk/MicsCentralApplicationTest.java
@@ -0,0 +1,92 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk; + +import com.codahale.metrics.health.HealthCheckRegistry; +import io.dropwizard.jersey.setup.JerseyEnvironment; +import io.dropwizard.jetty.setup.ServletEnvironment; +import io.dropwizard.setup.Environment; +import org.easymock.EasyMock; +import org.eclipse.jetty.servlets.CrossOriginFilter; +import org.junit.Test; +import org.powermock.reflect.Whitebox; + +import javax.servlet.FilterRegistration; + +import static org.easymock.EasyMock.*; +import static org.junit.Assert.assertEquals; +import static org.powermock.api.easymock.PowerMock.replay; + +public class MicsCentralApplicationTest { + + @Test + public void testGetName() { + assertEquals( "micsCentral", new MicsCentralApplication().getName()); + } + + @Test + public void testRun() { + + MicsCentralConfiguration conf = createConfiguration(); + MicsCentralApplication mca = new MicsCentralApplication(); + mca.run(conf, createMockedEnvironment()); + + } + + @Test + public void testRun2() throws Exception { + MicsCentralApplication mca = new MicsCentralApplication(); + Whitebox.invokeMethod(mca, "configureCors", createMockedEnvironment() ); + } + + @Test + public void testInitialize() { + new MicsCentralApplication().initialize(null); + } + + private MicsCentralConfiguration createConfiguration() { + MicsCentralConfiguration c = new MicsCentralConfiguration(); + c.setServicesDistributionFileName("src/test/resources/testServiceDistributions.json"); + c.setProxyHost(null); + c.setProxyPort(null); + return c; + } + + private Environment createMockedEnvironment() { + FilterRegistration.Dynamic cors = EasyMock.createMock(FilterRegistration.Dynamic.class); + expect(cors.setInitParameter(anyString(), anyString())).andReturn( Boolean.TRUE ).anyTimes(); + cors.addMappingForUrlPatterns(anyObject(), anyBoolean(), anyString()); + expectLastCall(); + replay( cors ); + + ServletEnvironment se = EasyMock.createMock(ServletEnvironment.class); + expect(se.addFilter(eq("CORS"), eq(CrossOriginFilter.class))).andReturn(cors).anyTimes(); + replay(se); + + JerseyEnvironment je = EasyMock.createMock(JerseyEnvironment.class); + je.register(anyObject()); + expectLastCall(); + + HealthCheckRegistry hcr = EasyMock.createMock(HealthCheckRegistry.class); + hcr.register(anyString(), anyObject()); + expectLastCall(); + + Environment environment = EasyMock.createMock( Environment.class ); + expect( environment.servlets() ).andReturn(se).anyTimes(); + expect( environment.jersey() ).andReturn(je).anyTimes(); + expect( environment.healthChecks() ).andReturn(hcr).anyTimes(); + replay( environment ); + verify( environment ); + return environment; + } +}
diff --git a/src/test/java/org/eclipse/openk/api/ServiceDistributionClusterTest.java b/src/test/java/org/eclipse/openk/api/ServiceDistributionClusterTest.java new file mode 100644 index 0000000..21341a1 --- /dev/null +++ b/src/test/java/org/eclipse/openk/api/ServiceDistributionClusterTest.java
@@ -0,0 +1,82 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.api; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Test; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import static junit.framework.TestCase.assertEquals; + +public class ServiceDistributionClusterTest { + + private ServiceDistributionCluster.ServiceDistribution createDistribution( + boolean active, String name, String host, String urlPath, String healthUrlPath, String protocol, + Integer portApp, Integer portHealth, String description) { + + ServiceDistributionCluster.ServiceDistribution sd = new ServiceDistributionCluster.ServiceDistribution(); + sd.setActive(true); + sd.setName(name); + sd.setHost(host); + sd.setUrlPath(urlPath); + if( healthUrlPath != null) { + sd.setHealthUrlPath(healthUrlPath); + } + sd.setProtocol(protocol); + sd.setPortApp(portApp); + sd.setPortHealth(portHealth); + sd.setDescription(description); + + return sd; + } + + @Test + public void testPojo() throws IOException { + List<ServiceDistributionCluster.ServiceDistribution> distList = new ArrayList<>(); + distList.add(createDistribution(true, "Hugo", "1.2.3.4", "19/eleven", + "healthy","httpx", + 1000, 2000, "Hugo ist toll")); + distList.add(createDistribution(false, "Bruno Haferkamp", "2.3.4.5", "seven/of/nine", "httpxy", + null,10, null, "Bruno ist noch toller")); + ServiceDistributionCluster.ServiceDistribution[] arr + = new ServiceDistributionCluster.ServiceDistribution[distList.size()]; + ServiceDistributionCluster cluster = new ServiceDistributionCluster(); + + cluster.setDistributions(distList.toArray(arr)); + cluster.setClustername("Kleister"); + cluster.setActive(true); + cluster.setDescription("The cluster of kleister!"); + + ObjectMapper om = new ObjectMapper(); + String json = om.writeValueAsString(cluster); + + ServiceDistributionCluster inCluster = om.readValue(json, ServiceDistributionCluster.class); + + assertEquals(cluster.getClustername(), inCluster.getClustername()); + assertEquals(cluster.isActive(), inCluster.isActive()); + assertEquals(cluster.getDescription(), inCluster.getDescription()); + for (int i = 0; i < cluster.getDistributions().length; i++) { + assertEquals(cluster.getDistributions()[i].getName(), inCluster.getDistributions()[i].getName()); + assertEquals(cluster.getDistributions()[i].getHost(), inCluster.getDistributions()[i].getHost()); + assertEquals(cluster.getDistributions()[i].getUrlPath(), inCluster.getDistributions()[i].getUrlPath()); + assertEquals(cluster.getDistributions()[i].isActive(), inCluster.getDistributions()[i].isActive()); + assertEquals(cluster.getDistributions()[i].getPortApp(), inCluster.getDistributions()[i].getPortApp()); + assertEquals(cluster.getDistributions()[i].getPortHealth(), inCluster.getDistributions()[i].getPortHealth()); + assertEquals(cluster.getDistributions()[i].getDescription(), inCluster.getDistributions()[i].getDescription()); + assertEquals(cluster.getDistributions()[i].getProtocol(), inCluster.getDistributions()[i].getProtocol()); + } + } +}
diff --git a/src/test/java/org/eclipse/openk/api/ServiceRequestEnvelopeTest.java b/src/test/java/org/eclipse/openk/api/ServiceRequestEnvelopeTest.java new file mode 100644 index 0000000..8e8258f --- /dev/null +++ b/src/test/java/org/eclipse/openk/api/ServiceRequestEnvelopeTest.java
@@ -0,0 +1,58 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.api; + +import org.glassfish.jersey.internal.util.Base64; +import org.junit.Test; + +import static junit.framework.TestCase.assertEquals; + +public class ServiceRequestEnvelopeTest { + + @Test + public void testPojo() { + final String payload = "Testme Accurate"; + final String payloadEncoded = Base64.encodeAsString(payload); + ServiceRequestEnvelope env = new ServiceRequestEnvelope(); + env.setMethod("POST"); + env.setPayloadEncode(payload); + env.setUriFragment("Fraggel"); + env.setServiceName("Salve"); + + ServiceRequestEnvelope.HttpHeader[] headers = new ServiceRequestEnvelope.HttpHeader[2]; + headers[0] = new ServiceRequestEnvelope.HttpHeader(); + headers[0].setAttribute("1stAttr"); + headers[0].setValue("1stValue"); + headers[1] = new ServiceRequestEnvelope.HttpHeader(); + headers[1].setAttribute("2ndAttr"); + headers[1].setValue("2ndValue"); + env.setHeaders(headers); + + assertEquals("POST", env.getMethod()); + assertEquals(payload, env.getPayloadDecode()); + assertEquals(payloadEncoded, env.getPayload()); + env.setPayload(payload); + assertEquals(payload, env.getPayload()); + assertEquals("Fraggel", env.getUriFragment()); + assertEquals("Salve", env.getServiceName()); + assertEquals(2, env.getHeaders().length); + assertEquals("2ndAttr", env.getHeaders()[1].getAttribute()); + assertEquals("1stValue", env.getHeaders()[0].getValue()); + + env.setPayload(null); + assertEquals("", env.getPayloadDecode()); + + env.setPayload(""); + assertEquals("", env.getPayloadDecode()); + } +}
diff --git a/src/test/java/org/eclipse/openk/api/VersionInfoTest.java b/src/test/java/org/eclipse/openk/api/VersionInfoTest.java new file mode 100644 index 0000000..fa9b197 --- /dev/null +++ b/src/test/java/org/eclipse/openk/api/VersionInfoTest.java
@@ -0,0 +1,36 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.api; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Test; + +import java.io.IOException; + +import static org.junit.Assert.assertEquals; + +public class VersionInfoTest { + + @Test + public void testGetVersionInfo() throws IOException { + VersionInfo vi = new VersionInfo(); + vi.setBackendVersion("123"); + + ObjectMapper om = new ObjectMapper(); + String jsonString = om.writeValueAsString(vi); + + VersionInfo vi2 = om.readValue(jsonString, VersionInfo.class); + + assertEquals(vi.getBackendVersion(), vi2.getBackendVersion()); + } +}
diff --git a/src/test/java/org/eclipse/openk/core/common/GsonUTCDateAdapterTest.java b/src/test/java/org/eclipse/openk/core/common/GsonUTCDateAdapterTest.java new file mode 100644 index 0000000..06c574c --- /dev/null +++ b/src/test/java/org/eclipse/openk/core/common/GsonUTCDateAdapterTest.java
@@ -0,0 +1,66 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.common; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSerializationContext; +import org.junit.Test; + +import java.lang.reflect.Type; +import java.util.Calendar; + +public class GsonUTCDateAdapterTest { + + @Test + public void serializeTest() { + GsonUTCDateAdapter gsonUTCDateAdapter = new GsonUTCDateAdapter(); + Calendar calendar = Calendar.getInstance(); + java.util.Date date = calendar.getTime(); + Type type = new Type() { + @Override + public String getTypeName() { + return null; + } + }; + JsonSerializationContext jsonSerializationContext = new JsonSerializationContext() { + @Override + public JsonElement serialize(Object o) { + return null; + } + + @Override + public JsonElement serialize(Object o, Type type) { + return null; + } + }; + + JsonElement je = gsonUTCDateAdapter.serialize(date, type, jsonSerializationContext); + + // run through generator code base + JsonGeneratorBase.getGson(); + + + JsonDeserializationContext jsonDeserializationContext = new JsonDeserializationContext() { + @Override + public <T> T deserialize(JsonElement jsonElement, Type type) throws JsonParseException { + return null; + } + }; + + + gsonUTCDateAdapter.deserialize(je, type, jsonDeserializationContext); + } + +}
diff --git a/src/test/java/org/eclipse/openk/core/common/util/ResourceLoaderBaseTest.java b/src/test/java/org/eclipse/openk/core/common/util/ResourceLoaderBaseTest.java new file mode 100644 index 0000000..9247f87 --- /dev/null +++ b/src/test/java/org/eclipse/openk/core/common/util/ResourceLoaderBaseTest.java
@@ -0,0 +1,27 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.common.util; + + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class ResourceLoaderBaseTest { + @Test + public void testloadStringFromResourceError() { + ResourceLoaderBase rlb = new ResourceLoaderBase(); + String str = rlb.loadStringFromResource("UNKNOWN_FILE"); + assertEquals("", str); + } +}
diff --git a/src/test/java/org/eclipse/openk/core/controller/BaseWebServiceTest.java b/src/test/java/org/eclipse/openk/core/controller/BaseWebServiceTest.java new file mode 100644 index 0000000..2b5ac28 --- /dev/null +++ b/src/test/java/org/eclipse/openk/core/controller/BaseWebServiceTest.java
@@ -0,0 +1,75 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.controller; + +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.openk.core.common.util.ResourceLoaderBase; +import org.junit.Test; +import org.powermock.reflect.Whitebox; +import org.eclipse.openk.core.exceptions.HttpStatusException; + +import javax.ws.rs.core.Response; + +import static org.junit.Assert.*; + +public class BaseWebServiceTest extends ResourceLoaderBase { + private static final org.apache.log4j.Logger EMPTYLOGGER = org.apache.log4j.Logger + .getLogger(BaseWebServiceTest.class.getName()); + + private BaseWebService createBaseWebService() { + return new BaseWebService(EMPTYLOGGER); + } + + private BaseWebService.Invokable createInvokable( Object o, Exception e2Return ) { + return () -> { + if( e2Return == null ) { + return o; + } + else { + throw e2Return; + } + }; + } + + @Test + public void testInvokeRunnableOK() { + Response r = createBaseWebService().invokeRunnable(createInvokable("Test Ok", null)); + assertEquals(HttpStatus.OK_200, r.getStatus()); + } + + @Test + public void testInvokeRunnable_HttpStatusException() { + Response r = createBaseWebService().invokeRunnable(createInvokable(null, + new HttpStatusException(HttpStatus.BAD_REQUEST_400))); + assertEquals(HttpStatus.BAD_REQUEST_400, r.getStatus()); + } + + @Test + public void testInvokeRunnable_GeneralException() { + Response r = createBaseWebService().invokeRunnable(createInvokable( null, + new Exception("hallodri"))); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR_500, r.getStatus()); + } + + @Test + public void testGetVersionString() throws Exception { + BaseWebService bws = createBaseWebService(); + String version = (String) Whitebox.invokeMethod(bws, "getVersionString"); + assertNotNull(version); + assertNotEquals(version, ""); + } + + + + +}
diff --git a/src/test/java/org/eclipse/openk/core/controller/CentralControllerTest.java b/src/test/java/org/eclipse/openk/core/controller/CentralControllerTest.java new file mode 100644 index 0000000..cfd8e84 --- /dev/null +++ b/src/test/java/org/eclipse/openk/core/controller/CentralControllerTest.java
@@ -0,0 +1,154 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.controller; + +import org.easymock.EasyMock; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.openk.api.VersionInfo; +import org.eclipse.openk.core.common.util.ResourceLoaderBase; +import org.eclipse.openk.core.communication.RestServiceWrapper; +import org.junit.Test; +import org.powermock.reflect.Whitebox; +import org.eclipse.openk.api.ServiceDistributionCluster; +import org.eclipse.openk.core.exceptions.HttpStatusException; + +import static org.easymock.EasyMock.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + + +public class CentralControllerTest { + + private ServiceDistributionCluster baseTestReadServerDistribution(String clustername, String jsonFile) throws Exception { + ResourceLoaderBase resourceLoaderBase = new ResourceLoaderBase(); + String json = resourceLoaderBase.loadStringFromResource(jsonFile); + + ServicesConfigCache scc = ServicesConfigCache.getInstance(); + ServiceDistributionCluster[] sdc = (ServiceDistributionCluster[]) + Whitebox.invokeMethod(scc,"readServerDistributionFromText", json); + + Whitebox.setInternalState(scc, "cache", sdc); + + CentralController be = new CentralController(); + + ServiceDistributionCluster ret = be.readServerDistribution(clustername); + + return ret; + } + + @Test + public void testReadServerDistribution() throws Exception { + + ServiceDistributionCluster sdc = baseTestReadServerDistribution("elogbook.openK", "testServiceDistributions.json"); + + assertEquals("elogbook.openK", sdc.getClustername()); + assertEquals(2, sdc.getDistributions().length); + assertEquals("172.18.22.160", sdc.getDistributions()[0].getHost()); + } + + @Test + public void testFailReadServerDistribution() throws Exception { + try { + baseTestReadServerDistribution("doesntMatter", "testServiceDist_False.json"); + } catch( HttpStatusException e ) { + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR_500, e.getHttpStatus()); + } + } + + @Test + public void testReadServerDistribution_notfound() throws Exception { + try { + ServiceDistributionCluster sdc = baseTestReadServerDistribution("invalidCluster", "testServiceDistributions.json"); + } catch( HttpStatusException e ) { + assertEquals(HttpStatus.NOT_FOUND_404, e.getHttpStatus()); + } + } + + @Test + public void testReadServerDistribution_activeInactive() throws Exception { + ServiceDistributionCluster sdc = baseTestReadServerDistribution( "elogbook.openk", "testServiceDistributionsTwo_OneIsInactive.json"); + + assertEquals( 1, sdc.getDistributions().length); + assertTrue( sdc.getDistributions()[0].isActive()); + assertEquals( "172.18.22.160", sdc.getDistributions()[0].getHost()); + } + + @Test (expected = HttpStatusException.class) + public void testFindDistribution_notFound() throws Exception { + ServiceDistributionCluster sdc = baseTestReadServerDistribution("elogbook.openK", "testServiceDistributions.json"); + CentralController cc = new CentralController(); + try { + Whitebox.invokeMethod(cc, "findDistribution", "elogbook.openK", "testService"); + } + catch( HttpStatusException hse ) { + assertEquals(HttpStatus.NOT_FOUND_404, hse.getHttpStatus()); + throw hse; + } + } + + @Test + public void testFindDistribution_ok() throws Exception { + ServiceDistributionCluster sdc = baseTestReadServerDistribution("elogbook.openK", "testServiceDistributions.json"); + CentralController cc = new CentralController(); + + Whitebox.invokeMethod(cc, "findDistribution", "elogbook.openK", "auth-n-auth.mics"); + + } + + + @Test (expected = HttpStatusException.class) + public void testFindDistribution_clusterNotFound() throws Exception { + ServiceDistributionCluster sdc = baseTestReadServerDistribution("elogbook.openK", "testServiceDistributions.json"); + CentralController cc = new CentralController(); + try { + Whitebox.invokeMethod(cc, "findDistribution", "invalidCluster", "auth-n-auth.mics"); + } + catch( HttpStatusException hse ) { + assertEquals(HttpStatus.NOT_FOUND_404, hse.getHttpStatus()); + throw hse; + } + } + + @Test + public void testGetVersionInfo() throws Exception { + CentralController cc = new CentralController(); + assertEquals("Bruno2.0", cc.getVersionInfo("Bruno2.0").getBackendVersion()); + assertTrue(Whitebox.invokeMethod(cc, "createRestServiceWrapper", true) instanceof RestServiceWrapper ); + } + + + @Test + public void testHealthCheck() throws Exception { + ServiceDistributionCluster sdc = baseTestReadServerDistribution("elogbook.openK", "testServiceDistributions.json"); + CentralController cc = new CentralController() { + @Override + protected RestServiceWrapper createRestServiceWrapper( boolean isHttps ) { + RestServiceWrapper wrapper = EasyMock.createMock( RestServiceWrapper.class ); + try { + expect( wrapper.performGetRequest( anyObject()) ).andReturn("Ist OK!").anyTimes(); + } catch (HttpStatusException e) { + return null; + } + replay( wrapper ); + verify( wrapper ); + return wrapper; + } + + }; + + + assertEquals("Ist OK!", cc.getServiceHealthState("elogbook.openK", "auth-n-auth.mics")); + assertEquals("Ist OK!", cc.getServiceHealthState("elogbook.openK", "homie")); + + } +}
diff --git a/src/test/java/org/eclipse/openk/core/controller/DispatchControllerTest.java b/src/test/java/org/eclipse/openk/core/controller/DispatchControllerTest.java new file mode 100644 index 0000000..6d7aad3 --- /dev/null +++ b/src/test/java/org/eclipse/openk/core/controller/DispatchControllerTest.java
@@ -0,0 +1,114 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.controller; + +import org.easymock.EasyMock; +import org.eclipse.jetty.http.HttpStatus; +import org.junit.Before; +import org.junit.Test; +import org.powermock.reflect.Whitebox; +import org.eclipse.openk.api.ServiceDistributionCluster; +import org.eclipse.openk.api.ServiceRequestEnvelope; +import org.eclipse.openk.core.common.JsonGeneratorBase; +import org.eclipse.openk.core.common.util.ResourceLoaderBase; +import org.eclipse.openk.core.communication.RestServiceWrapper; +import org.eclipse.openk.core.exceptions.HttpStatusException; + +import javax.ws.rs.core.Response; + +import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.anyString; +import static org.junit.Assert.assertEquals; + +public class DispatchControllerTest extends ResourceLoaderBase { + + @Before + public void init() { + String clusterString = this.loadStringFromResource("servicesDistributionTest.json"); + ServiceDistributionCluster[] cluster = JsonGeneratorBase.getGson() + .fromJson(clusterString, ServiceDistributionCluster[].class); + ServicesConfigCache cache = ServicesConfigCache.getInstance(); + Whitebox.setInternalState(cache, "cache", cluster); + + + } + + @Test + public void testDispatch_ok() throws HttpStatusException { + Response response = Response.ok().entity("{ret: '111'}").build(); + final RestServiceWrapper rester = EasyMock.createMock(RestServiceWrapper.class); + EasyMock.expect(rester.performHttpRequest(anyObject(), + anyString(), anyObject(), anyString())).andReturn(response); + EasyMock.replay(rester); + ServiceRequestEnvelope envelope = JsonGeneratorBase.getGson().fromJson( + loadStringFromResource("serviceRequestEnvelope.json"), ServiceRequestEnvelope.class); + + + DispatchController controller = new DispatchController() { + @Override + protected RestServiceWrapper createRestServiceWrapper(boolean b) { + return rester; + } + }; + + Response resp2 = controller.dispatch("elogbook.openk", envelope); + assertEquals(HttpStatus.OK_200, resp2.getStatus()); + + } + + @Test(expected = HttpStatusException.class) + public void testDispatch_InvCluster() throws HttpStatusException { + + Response response = Response.ok().entity("{ret: '111'}").build(); + final RestServiceWrapper rester = EasyMock.createMock(RestServiceWrapper.class); + EasyMock.expect(rester.performHttpRequest(anyObject(), + anyString(), anyObject(), anyString())).andReturn(response); + EasyMock.replay(rester); + ServiceRequestEnvelope envelope = JsonGeneratorBase.getGson().fromJson( + loadStringFromResource("serviceRequestEnvelope.json"), ServiceRequestEnvelope.class); + + + DispatchController controller = new DispatchController() { + @Override + protected RestServiceWrapper createRestServiceWrapper(boolean b) { + return rester; + } + }; + + try { + controller.dispatch("invalid", envelope); + } catch (HttpStatusException hse) { + assertEquals(HttpStatus.NOT_FOUND_404, hse.getHttpStatus()); + throw hse; + } + } + + @Test(expected = HttpStatusException.class) + public void testResolveMethod() throws Exception { + DispatchController ctrl = new DispatchController(); + assertEquals(RestServiceWrapper.HttpMethod.GET, Whitebox.invokeMethod(ctrl, "resolveMethod", "get")); + assertEquals(RestServiceWrapper.HttpMethod.POST, Whitebox.invokeMethod(ctrl, "resolveMethod", "Post")); + assertEquals(RestServiceWrapper.HttpMethod.DELETE, Whitebox.invokeMethod(ctrl, "resolveMethod", "DELETE")); + assertEquals(RestServiceWrapper.HttpMethod.PUT, Whitebox.invokeMethod(ctrl, "resolveMethod", "put")); + + String s; + try { + s = Whitebox.invokeMethod(ctrl, "resolveMethod", "invalid"); + } catch (HttpStatusException hse) { + // the correct test path goes in here!!!!!! + assertEquals(HttpStatus.METHOD_NOT_ALLOWED_405, hse.getHttpStatus()); + throw hse; + } + } + +}
diff --git a/src/test/java/org/eclipse/openk/core/controller/ServicesConfigCacheTest.java b/src/test/java/org/eclipse/openk/core/controller/ServicesConfigCacheTest.java new file mode 100644 index 0000000..e699fca --- /dev/null +++ b/src/test/java/org/eclipse/openk/core/controller/ServicesConfigCacheTest.java
@@ -0,0 +1,73 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.controller; + +import org.eclipse.jetty.http.HttpStatus; +import org.junit.Test; +import org.powermock.reflect.Whitebox; +import org.eclipse.openk.api.ServiceDistributionCluster; +import org.eclipse.openk.core.common.util.ResourceLoaderBase; +import org.eclipse.openk.core.exceptions.HttpStatusException; + +import static org.junit.Assert.assertEquals; + + +public class ServicesConfigCacheTest { + + private ServiceDistributionCluster[] baseTestReadServerDistribution(String jsonFile) throws Exception { + ResourceLoaderBase resourceLoaderBase = new ResourceLoaderBase(); + String json = resourceLoaderBase.loadStringFromResource(jsonFile); + + ServicesConfigCache scc = ServicesConfigCache.getInstance(); + return Whitebox.invokeMethod(scc, "readServerDistributionFromText", json); + } + + @Test + public void testReadServerDistribution() throws Exception { + + ServiceDistributionCluster[] sdc = baseTestReadServerDistribution("testServiceDistributions.json"); + + assertEquals("elogbook.openK", sdc[0].getClustername()); + assertEquals(2, sdc[0].getDistributions().length); + assertEquals("172.18.22.160", sdc[0].getDistributions()[0].getHost()); + } + + @Test + public void testFailReadServerDistribution() throws Exception { + try { + baseTestReadServerDistribution("testServiceDist_False.json"); + } catch( HttpStatusException e ) { + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR_500, e.getHttpStatus()); + } + } + + @Test + public void testReadServerDistribution_FileNotExist() throws Exception { + try { + baseTestReadServerDistribution("Nowhere.json"); + } catch (HttpStatusException e) { + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR_500, e.getHttpStatus()); + } + } + + @Test + public void testReadServerDistribution_FileNotExistEither() throws Exception { + try { + ServicesConfigCache.getInstance().readServerDistribution("Nowhere.json"); + } catch (HttpStatusException e) { + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR_500, e.getHttpStatus()); + } + } + + +}
diff --git a/src/test/java/org/eclipse/openk/core/controller/ServicesConfigCacheTimerTaskTest.java b/src/test/java/org/eclipse/openk/core/controller/ServicesConfigCacheTimerTaskTest.java new file mode 100644 index 0000000..e8f6557 --- /dev/null +++ b/src/test/java/org/eclipse/openk/core/controller/ServicesConfigCacheTimerTaskTest.java
@@ -0,0 +1,71 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.controller; + +import org.easymock.EasyMock; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.openk.core.exceptions.HttpStatusException; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.powermock.reflect.Whitebox; + +import static org.easymock.EasyMock.*; + +public class ServicesConfigCacheTimerTaskTest { + private static ServicesConfigCache saveScc; + + @BeforeClass + public static void SaveState() { + saveScc = Whitebox.getInternalState(ServicesConfigCache.class, "instance"); + + } + + @AfterClass + public static void tearDown() { + Whitebox.setInternalState(ServicesConfigCache.class, "instance", saveScc); + } + + @Test + public void testRun() throws Exception { + // ------------------ Prepare Test ---------------------- + final String EXCEPTION_TEXT = "Exception"; + + // just to reach the sonar quality gate + Whitebox.invokeConstructor(InitServicesConfigCacheJob.class); + + ServicesConfigCache scc = EasyMock.createMock(ServicesConfigCache.class); + scc.readServerDistribution(eq(EXCEPTION_TEXT)); + expectLastCall().andThrow(new HttpStatusException(HttpStatus.INTERNAL_SERVER_ERROR_500)).anyTimes(); + + scc.readServerDistribution(not(eq(EXCEPTION_TEXT))); + expectLastCall().anyTimes(); + + replay( scc ); + + Whitebox.setInternalState(ServicesConfigCache.class, "instance", scc); + + + // ---------------------------- Test it ------------------------------------------ + ServicesConfigCacheTimerTask task = new ServicesConfigCacheTimerTask(EXCEPTION_TEXT); + + task.run(); + + // should run without problems + ServicesConfigCacheTimerTask task2 = new ServicesConfigCacheTimerTask("No Error"); + task2.run(); + + tearDown(); + } + +}
diff --git a/src/test/java/org/eclipse/openk/core/exceptions/HttpStatusExceptionTest.java b/src/test/java/org/eclipse/openk/core/exceptions/HttpStatusExceptionTest.java new file mode 100644 index 0000000..7ffc901 --- /dev/null +++ b/src/test/java/org/eclipse/openk/core/exceptions/HttpStatusExceptionTest.java
@@ -0,0 +1,27 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.core.exceptions; + + +import org.eclipse.jetty.http.HttpStatus; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class HttpStatusExceptionTest { + @Test + public void testAll() { + HttpStatusException hse = new HttpStatusException( 200 ); + assertEquals(HttpStatus.OK_200, hse.getHttpStatus()); + } +}
diff --git a/src/test/java/org/eclipse/openk/health/ConfigFilePresentHealthCheckTest.java b/src/test/java/org/eclipse/openk/health/ConfigFilePresentHealthCheckTest.java new file mode 100644 index 0000000..0ebe951 --- /dev/null +++ b/src/test/java/org/eclipse/openk/health/ConfigFilePresentHealthCheckTest.java
@@ -0,0 +1,54 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.health; + +import com.codahale.metrics.health.HealthCheck; +import org.eclipse.openk.api.ServiceDistributionCluster; +import org.eclipse.openk.core.controller.ServicesConfigCache; +import org.junit.Test; +import org.powermock.reflect.Whitebox; + +import static junit.framework.TestCase.assertFalse; +import static org.junit.Assert.assertTrue; + +public class ConfigFilePresentHealthCheckTest { + private boolean isHealthy(ConfigFilePresentHealthCheck hc) throws Exception { + HealthCheck.Result r = Whitebox.invokeMethod(hc, "check"); + return r.isHealthy(); + } + + @Test + public void testConfigFilePresent_False() throws Exception { + ServicesConfigCache scc = ServicesConfigCache.getInstance(); + ServiceDistributionCluster[] oldCache = scc.getCache(); + + try { + ConfigFilePresentHealthCheck hc = new ConfigFilePresentHealthCheck(); + + // test with invalid cluster + Whitebox.setInternalState(scc, "cache", (Object) null); + assertFalse(isHealthy(hc)); + + // test with invalid cluster + Whitebox.setInternalState(scc, "cache", new ServiceDistributionCluster[0]); + assertFalse(isHealthy(hc)); + + ServiceDistributionCluster[] arr = new ServiceDistributionCluster[1]; + arr[0] = new ServiceDistributionCluster(); + Whitebox.setInternalState(scc, "cache", arr); + assertTrue(isHealthy(hc)); + } finally { + Whitebox.setInternalState(scc, "cache", oldCache); + } + } +}
diff --git a/src/test/java/org/eclipse/openk/resources/MicsCentralResourceTest.java b/src/test/java/org/eclipse/openk/resources/MicsCentralResourceTest.java new file mode 100644 index 0000000..4597aef --- /dev/null +++ b/src/test/java/org/eclipse/openk/resources/MicsCentralResourceTest.java
@@ -0,0 +1,39 @@ +/** +****************************************************************************** +* Copyright © 2018 PTA GmbH. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* +* http://www.eclipse.org/legal/epl-v10.html +* +****************************************************************************** +*/ + +package org.eclipse.openk.resources; + +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.openk.core.controller.ServicesConfigCache; +import org.eclipse.openk.core.exceptions.HttpStatusException; +import org.junit.Test; + +import javax.ws.rs.core.Response; + +import static junit.framework.TestCase.assertNotNull; +import static org.junit.Assert.assertEquals; + +public class MicsCentralResourceTest { + @Test + public void testGetVersionInfo() { + Response r = new MicsCentralResource().getVersionInfo(); + assertNotNull( r ); + } + + @Test + public void testGetServiceDistribution() throws HttpStatusException { + ServicesConfigCache.getInstance().readServerDistribution("servicesDistributionDevLocal.json"); + Response r = new MicsCentralResource().getServiceDistribution("elogbook.openk" ); + + assertEquals(HttpStatus.OK_200, r.getStatus()); + } +}
diff --git a/src/test/resources/serviceRequestEnvelope.json b/src/test/resources/serviceRequestEnvelope.json new file mode 100644 index 0000000..9722f58 --- /dev/null +++ b/src/test/resources/serviceRequestEnvelope.json
@@ -0,0 +1,17 @@ +{ + "serviceName": "auth-n-auth.mics", + "isHttps": false, + "method": "GET", + "uriFragment": "versionInfo", + "payload": "eyAiYmFja2VuZFZlcnNpb24iOiAiMC4xLjMtU05BUFNIT1QifQ==", + "headers": [ + { + "attribute": "Content-Type", + "value": "application/json" + }, + { + "attribute": "accept", + "value": "application/json" + } + ] +} \ No newline at end of file
diff --git a/src/test/resources/servicesDistributionTest.json b/src/test/resources/servicesDistributionTest.json new file mode 100644 index 0000000..f91ddc5 --- /dev/null +++ b/src/test/resources/servicesDistributionTest.json
@@ -0,0 +1,20 @@ +[ + { + "active": "true", + "clustername": "elogbook.openK", + "description": "elogbook service cluster for openKonsequenz", + "distributions": [ + { + "active": "true", + "name": "auth-n-auth.mics", + "protocol": "http", + "host": "172.18.22.160", + "urlPath": "/authNAuth", + "healthUrlPath": "/portal/rest/beservice", + "portApp": "9002", + "portHealth": "9003", + "description": "Authentication Service" + } + ] + } +] \ No newline at end of file
diff --git a/src/test/resources/testServiceDist_False.json b/src/test/resources/testServiceDist_False.json new file mode 100644 index 0000000..bf87303 --- /dev/null +++ b/src/test/resources/testServiceDist_False.json
@@ -0,0 +1,19 @@ +[ + { + "active": "true", + + "description": "elogbook service cluster for openKonsequenz", + "distributions": [ + { + "active": "true", + "name": "auth-n-auth.mics", + "protocol": "http", + "host": "172.18.22.160", + "urlPath": "/authNAuth", + "portApp": "9002", + "portHealth": "9003", + "description": "Authentication Service" + } + ] + } +] \ No newline at end of file
diff --git a/src/test/resources/testServiceDistributions.json b/src/test/resources/testServiceDistributions.json new file mode 100644 index 0000000..0563fc1 --- /dev/null +++ b/src/test/resources/testServiceDistributions.json
@@ -0,0 +1,31 @@ +[ + { + "active": "true", + "clustername": "elogbook.openK", + "description": "elogbook service cluster for openKonsequenz", + "distributions": [ + { + "active": "true", + "name": "auth-n-auth.mics", + "protocol": "http", + "host": "172.18.22.160", + "urlPath": "/authNAuth", + "healthUrlPath": "/portal/rest/beservice", + "portApp": "9002", + "portHealth": "9003", + "description": "Authentication Service" + }, + { + "active": "true", + "name": "homie", + "protocol": "http", + "host": "172.18.22.160", + "urlPath": "/homie", + "healthUrlPath": "/portal/rest/beservice", + "portApp": "8080", + "portHealth": "8080", + "description": "Authentication Service" + } + ] + } +] \ No newline at end of file
diff --git a/src/test/resources/testServiceDistributionsTwo_OneIsInactive.json b/src/test/resources/testServiceDistributionsTwo_OneIsInactive.json new file mode 100644 index 0000000..0343c6c --- /dev/null +++ b/src/test/resources/testServiceDistributionsTwo_OneIsInactive.json
@@ -0,0 +1,57 @@ +[ + { + "active": "false", + "clustername": "elogbook.openK", + "description": "elogbook service cluster for openKonsequenz", + "distributions": [ + { + "active": "true", + "name": "auth-n-auth.mics", + "protocol": "http", + "host": "172.18.22.160", + "urlPath": "/authNAuth", + "portApp": "9002", + "portHealth": "9003", + "description": "Authentication Service" + }, + { + "active": "false", + "name": "auth-n-auth.mics", + "protocol": "http", + "host": "localhost", + "urlPath": "/mics/central", + "portApp": "9002", + "portHealth": "9003", + "description": "Authentication Service" + } + ] + }, + { + "active": "true", + "clustername": "elogbook.openK", + "description": "elogbook service cluster for openKonsequenz", + "distributions": [ + { + "active": "true", + "name": "auth-n-auth.mics", + "protocol": "http", + "host": "172.18.22.160", + "urlPath": "/authNAuth", + "healthUrlPath": "/portal/rest/beservice", + "portApp": "9002", + "portHealth": "9003", + "description": "Authentication Service" + }, + { + "active": "false", + "name": "auth-n-auth.mics", + "protocol": "http", + "host": "localhost", + "urlPath": "/mics/central", + "portApp": "9002", + "portHealth": "9003", + "description": "Authentication Service" + } + ] + } +] \ No newline at end of file
diff --git a/templates/markdown.hbs b/templates/markdown.hbs new file mode 100644 index 0000000..2a7e5cf --- /dev/null +++ b/templates/markdown.hbs
@@ -0,0 +1,107 @@ +#{{#info}}{{title}} + + +## {{join schemes " | "}}://{{host}}{{basePath}} + + +{{description}} + +{{#contact}} +[**Contact the developer**](mailto:{{email}}) +{{/contact}} + +**Version** {{version}} + +[**Terms of Service**]({{termsOfService}}) + +{{#license}}[**{{name}}**]({{url}}){{/license}} + +{{/info}} + +{{#if consumes}}**Consumes:** {{join consumes ", "}}{{/if}} + +{{#if produces}}**Produces:** {{join produces ", "}}{{/if}} + +{{#if securityDefinitions}} +# Security Definitions +{{/if}} +{{> security}} + +# APIs + +{{#each paths}} +## {{@key}} +{{#this}} +{{#get}} +### GET +{{> operation}} +{{/get}} + +{{#put}} +### PUT +{{> operation}} +{{/put}} + +{{#post}} +### POST + +{{> operation}} + +{{/post}} + +{{#delete}} +### DELETE +{{> operation}} +{{/delete}} + +{{#option}} +### OPTION +{{> operation}} +{{/option}} + +{{#patch}} +### PATCH +{{> operation}} +{{/patch}} + +{{#head}} +### HEAD +{{> operation}} +{{/head}} + +{{/this}} +{{/each}} + +# Definitions +{{#each definitions}} +## <a name="/definitions/{{key}}">{{@key}}</a> + +<table border="1"> + <tr> + <th>name</th> + <th>type</th> + <th>required</th> + <th>description</th> + <th>example</th> + </tr> + {{#each this.properties}} + <tr> + <td>{{@key}}</td> + <td> + {{#ifeq type "array"}} + {{#items.$ref}} + {{type}}[<a href="{{items.$ref}}">{{basename items.$ref}}</a>] + {{/items.$ref}} + {{^items.$ref}}{{type}}[{{items.type}}]{{/items.$ref}} + {{else}} + {{#$ref}}<a href="{{$ref}}">{{basename $ref}}</a>{{/$ref}} + {{^$ref}}{{type}}{{#format}} ({{format}}){{/format}}{{/$ref}} + {{/ifeq}} + </td> + <td>{{#required}}required{{/required}}{{^required}}optional{{/required}}</td> + <td>{{#description}}{{{description}}}{{/description}}{{^description}}-{{/description}}</td> + <td>{{example}}</td> + </tr> + {{/each}} +</table> +{{/each}} \ No newline at end of file
diff --git a/templates/operation.hbs b/templates/operation.hbs new file mode 100644 index 0000000..3ad3175 --- /dev/null +++ b/templates/operation.hbs
@@ -0,0 +1,73 @@ +{{#deprecated}}-deprecated-{{/deprecated}} +<a id="{{operationId}}">{{summary}}</a> + +{{description}} + +{{#if externalDocs.url}}{{externalDocs.description}}. [See external documents for more details]({{externalDocs.url}}) +{{/if}} + +{{#if security}} +#### Security +{{/if}} + +{{#security}} +{{#each this}} +* {{@key}} +{{#this}} * {{this}} +{{/this}} +{{/each}} +{{/security}} + +#### Request + +{{#if consumes}} +**Content-Type: ** {{join consumes ", "}}{{/if}} + +##### Parameters +{{#if parameters}} +<table border="1"> + <tr> + <th>Name</th> + <th>Located in</th> + <th>Required</th> + <th>Description</th> + <th>Default</th> + <th>Schema</th> + </tr> + {{/if}} + + {{#parameters}} + <tr> + <th>{{name}}</th> + <td>{{in}}</td> + <td>{{#if required}}yes{{else}}no{{/if}}</td> + <td>{{description}}{{#if pattern}} (**Pattern**: `{{pattern}}`){{/if}}</td> + <td> - </td> + {{#ifeq in "body"}} + <td> + {{#ifeq schema.type "array"}}Array[<a href="{{schema.items.$ref}}">{{basename schema.items.$ref}}</a>]{{/ifeq}} + {{#schema.$ref}}<a href="{{schema.$ref}}">{{basename schema.$ref}}</a> {{/schema.$ref}} + </td> + {{else}} + {{#ifeq type "array"}} + <td>Array[{{items.type}}] ({{collectionFormat}})</td> + {{else}} + <td>{{type}} {{#format}}({{format}}){{/format}}</td> + {{/ifeq}} + {{/ifeq}} + </tr> + {{/parameters}} + {{#if parameters}} +</table> +{{/if}} + + +#### Response + +{{#if produces}}**Content-Type: ** {{join produces ", "}}{{/if}} + + +| Status Code | Reason | Response Model | +|-------------|-------------|----------------| +{{#each responses}}| {{@key}} | {{description}} | {{#schema.$ref}}<a href="{{schema.$ref}}">{{basename schema.$ref}}</a>{{/schema.$ref}}{{#ifeq schema.type "array"}}Array[<a href="{{schema.items.$ref}}">{{basename schema.items.$ref}}</a>]{{/ifeq}}{{^schema}} - {{/schema}}| +{{/each}} \ No newline at end of file
diff --git a/templates/security.hbs b/templates/security.hbs new file mode 100644 index 0000000..94badab --- /dev/null +++ b/templates/security.hbs
@@ -0,0 +1,88 @@ +{{#each securityDefinitions}} +### {{@key}} +{{#this}} +{{#ifeq type "oauth2"}} +<table> + <tr> + <th>type</th> + <th colspan="2">{{type}}</th> + </tr> + {{#if description}} + <tr> + <th>description</th> + <th colspan="2">{{description}}</th> + </tr> + {{/if}} + {{#if authorizationUrl}} + <tr> + <th>authorizationUrl</th> + <th colspan="2">{{authorizationUrl}}</th> + </tr> + {{/if}} + {{#if flow}} + <tr> + <th>flow</th> + <th colspan="2">{{flow}}</th> + </tr> + {{/if}} + {{#if tokenUrl}} + <tr> + <th>tokenUrl</th> + <th colspan="2">{{tokenUrl}}</th> + </tr> + {{/if}} + {{#if scopes}} + <tr> + <td rowspan="3">scopes</td> + {{#each scopes}} + <td>{{@key}}</td> + <td>{{this}}</td> + </tr> + <tr> + {{/each}} + </tr> + {{/if}} +</table> +{{/ifeq}} +{{#ifeq type "apiKey"}} +<table> + <tr> + <th>type</th> + <th colspan="2">{{type}}</th> + </tr> + {{#if description}} + <tr> + <th>description</th> + <th colspan="2">{{description}}</th> + </tr> + {{/if}} + {{#if name}} + <tr> + <th>name</th> + <th colspan="2">{{name}}</th> + </tr> + {{/if}} + {{#if in}} + <tr> + <th>in</th> + <th colspan="2">{{in}}</th> + </tr> + {{/if}} +</table> +{{/ifeq}} +{{#ifeq type "basic"}} +<table> + <tr> + <th>type</th> + <th colspan="2">{{type}}</th> + </tr> + {{#if description}} + <tr> + <th>description</th> + <th colspan="2">{{description}}</th> + </tr> + {{/if}} +</table> +{{/ifeq}} +{{/this}} +{{/each}} \ No newline at end of file
diff --git a/templates/strapdown.html.hbs b/templates/strapdown.html.hbs new file mode 100644 index 0000000..fd359ff --- /dev/null +++ b/templates/strapdown.html.hbs
@@ -0,0 +1,10 @@ +<!DOCTYPE html> +<html> +<title>API Document</title> + +<xmp theme="united" style="display:none;"> + {{>markdown}} +</xmp> + +<script src="http://strapdownjs.com/v/0.2/strapdown.js"></script> +</html> \ No newline at end of file