-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Java Tender Loving Care #3
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,3 +10,4 @@ | |
/model/repos | ||
/entrypoint/repos | ||
|
||
build |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
= OpenFaas Java | ||
|
||
This project builds Java libraries and modules used by OpenFaas. | ||
|
||
This project uses https://gradle.org/[Gradle] build tool. | ||
|
||
This project publishes java libraries to https://search.maven.org/[Maven Central]. | ||
|
||
The libraries are used by the https://github.com/openfaas/templates[OpenFaas Java templates]. | ||
|
||
You will use these libraries as dependencies when building your functions. | ||
|
||
== Contributions to this project | ||
|
||
The project uses https://github.com/diffplug/spotless/tree/main/plugin-gradle#java[gradle-spotless-plugin] to take care of checking and formatting the source code. | ||
This ensures that contributions are always formatted in the same way. | ||
It also ensures files contain the proper license header. | ||
|
||
This is a https://docs.gradle.org/current/userguide/multi_project_builds.html[Multi-Project Gradle build] . | ||
It means we have multiple libraries published from this project. | ||
|
||
We use https://docs.gradle.org/current/userguide/publishing_maven.html[maven-publish] plugin to publish the libraries. | ||
|
||
== Making a release | ||
|
||
Releases are published to Maven Central. | ||
See https://issues.sonatype.org/browse/OSSRH-48617 and https://central.sonatype.org/pages/ossrh-guide.html . | ||
|
||
All of the release and publish steps are done by gradle. | ||
You will have to have write access to the staging repository and aprove the release. | ||
|
||
You will have to pass the release property: `./gradlew clean build -Prelease` . | ||
That will enable the tasks in the build responsible for publishing. | ||
|
||
You will also have to provide valid credentials via `ossrhUsername` and `ossrhPassword` . | ||
|
||
Publishing requires signing the artifacts and you will need to configure a https://docs.gradle.org/current/userguide/signing_plugin.html#sec:signatory_credentials[signatory] | ||
You can avoid the signing process by excluding the task `./gradlew build -x sign` . | ||
|
||
To configure a signatory you will need to add some properties to your `~/.gradle/gradle.properties` file . | ||
|
||
You will need to provide values for the properties defined in the `build.gradle` file: | ||
|
||
[source,groovy] | ||
---- | ||
signing { | ||
def signingKeyId = findProperty("openfaas.signingKeyId") | ||
def signingKey = findProperty("openfaas.signingKey") | ||
def signingPassword = findProperty("openfaas.signingPassword") | ||
// ... | ||
} | ||
---- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
plugins { | ||
id "com.diffplug.spotless" version "5.1.0" | ||
} | ||
|
||
allprojects { | ||
group = 'com.openfaas' | ||
} | ||
|
||
spotless { | ||
format 'misc', { | ||
// define the files to apply `misc` to | ||
target '*.gradle', '*/*.gradle', '*.md', '.gitignore' | ||
|
||
// define the steps to apply to those files | ||
trimTrailingWhitespace() | ||
indentWithSpaces(2) // or spaces. Takes an integer argument if you don't like 4 | ||
endWithNewline() | ||
} | ||
java { | ||
// don't need to set target, it is inferred from java | ||
target '**/src/*/java/**/*.java' | ||
|
||
importOrder() | ||
removeUnusedImports() | ||
|
||
// apply a specific flavor of google-java-format | ||
googleJavaFormat('1.8').aosp() | ||
// make sure every file has the following copyright header. | ||
// optionally, Spotless can set copyright years by digging | ||
// through git history (see "license" section below) | ||
licenseHeader "// Copyright (c) OpenFaaS Author(s) 2018. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,99 +1,98 @@ | ||
buildscript { | ||
group = 'com.openfaas' | ||
version = '0.1.0' | ||
} | ||
|
||
plugins { | ||
id 'java' | ||
id 'application' | ||
id 'maven' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @alexellis : maven plugin is deprecated an being removed. |
||
id 'signing' | ||
id 'java-library' | ||
id 'maven-publish' | ||
id 'signing' | ||
} | ||
|
||
signing { | ||
sign configurations.archives | ||
} | ||
description = 'OpenFaaS Function entry point' | ||
version = '0.1.0' | ||
|
||
task javadocJar(type: Jar) { | ||
classifier = 'javadoc' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This way of adding a javadoc and sources jars are also deprecated . https://docs.gradle.org/current/userguide/publishing_maven.html#publishing_maven:complete_example |
||
from javadoc | ||
} | ||
dependencies { | ||
api project(':model') | ||
|
||
task sourcesJar(type: Jar) { | ||
classifier = 'sources' | ||
from sourceSets.main.allSource | ||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0' | ||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.0' | ||
} | ||
|
||
mainClassName = 'App' | ||
|
||
dependencies { | ||
compile 'com.google.guava:guava:23.0' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guava is not used in any of the code here. Also, compile is deprecated in favor of other configurations:
|
||
testCompile 'junit:junit:4.12' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. junit 5 is better and since we don't have legacy tests why not use it. |
||
compile 'com.openfaas:model:0.1.1' | ||
test { | ||
useJUnitPlatform() | ||
} | ||
|
||
java { | ||
sourceCompatibility = JavaVersion.VERSION_1_8 | ||
targetCompatibility = JavaVersion.VERSION_1_8 | ||
jar { | ||
manifest { | ||
attributes 'Implementation-Title': 'OpenFaaS Function', | ||
'Implementation-Version': project.version | ||
} | ||
} | ||
|
||
repositories { | ||
jcenter() | ||
|
||
flatDir { | ||
dirs 'libs' | ||
} | ||
jcenter() | ||
} | ||
|
||
artifacts { | ||
archives javadocJar, sourcesJar | ||
java { | ||
sourceCompatibility = JavaVersion.VERSION_1_8 | ||
targetCompatibility = JavaVersion.VERSION_1_8 | ||
withJavadocJar() | ||
withSourcesJar() | ||
} | ||
|
||
uploadArchives { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. uploadArchives is deprecated and is going to be removed.
https://docs.gradle.org/current/userguide/java_plugin.html#sec:java_tasks |
||
repositories { | ||
flatDir { | ||
dirs 'repos' | ||
} | ||
|
||
mavenDeployer { | ||
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } | ||
|
||
repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { | ||
authentication(userName: ossrhUsername, password: ossrhPassword) | ||
} | ||
|
||
snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { | ||
authentication(userName: ossrhUsername, password: ossrhPassword) | ||
} | ||
publishing { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the new and recommended way of publishing artifacts with gradle. It should work but I haven't publish anything yet. |
||
publications { | ||
mavenJava(MavenPublication) { | ||
from components.java | ||
|
||
pom.project { | ||
name 'OpenFaaS model' | ||
packaging 'jar' | ||
// optionally artifactId can be defined here | ||
description 'OpenFaaS Model for function invocations.' | ||
url 'http://www.openfaas.com/' | ||
|
||
scm { | ||
connection 'scm:git:https://github.com/openfaas/templates' | ||
developerConnection 'scm:git:https://github.com/openfaas/templates' | ||
url 'https://github.com/openfaas/templates' | ||
} | ||
pom { | ||
url = 'http://www.openfaas.com/' | ||
description = 'OpenFaaS Function.' | ||
|
||
licenses { | ||
license { | ||
name 'MIT' | ||
url 'https://opensource.org/licenses/MIT' | ||
name = 'MIT' | ||
url = 'https://opensource.org/licenses/MIT' | ||
} | ||
} | ||
|
||
scm { | ||
connection = 'scm:git:https://github.com/openfaas/templates-sdk.git' | ||
developerConnection = 'scm:git:https://github.com/openfaas/templates-sdk.git' | ||
url = 'https://github.com/openfaas/templates-sdk/' | ||
} | ||
developers { | ||
developer { | ||
id 'openfaas' | ||
name 'OpenFaaS Ltd' | ||
email '[email protected]' | ||
id = 'openfaas' | ||
name = 'OpenFaaS Ltd' | ||
email = '[email protected]' | ||
} | ||
} | ||
} | ||
} | ||
} | ||
repositories { | ||
maven { | ||
def releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" | ||
def snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots/" | ||
|
||
url = project.hasProperty('release') ? releasesRepoUrl : snapshotsRepoUrl | ||
|
||
credentials(PasswordCredentials) { | ||
username = project.hasProperty('ossrhUsername') ? ossrhUsername : null; | ||
password = project.hasProperty('ossrhPassword')? ossrhPassword : null; | ||
} | ||
} | ||
} | ||
} | ||
|
||
signing { | ||
def signingKeyId = findProperty("openfaas.signingKeyId") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've updated this according to the documentation |
||
def signingKey = findProperty("openfaas.signingKey") | ||
def signingPassword = findProperty("openfaas.signingPassword") | ||
useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword) | ||
|
||
sign publishing.publications.mavenJava | ||
} | ||
|
||
javadoc { | ||
if(JavaVersion.current().isJava9Compatible()) { | ||
options.addBooleanOption('html5', true) | ||
} | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,19 @@ | ||
// Copyright (c) OpenFaaS Author(s) 2018. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
package com.openfaas.entrypoint; | ||
|
||
import com.openfaas.model.*; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Star imports are not recommended in Java because they hide dependency on classes. |
||
import com.sun.net.httpserver.Headers; | ||
import com.sun.net.httpserver.HttpExchange; | ||
import com.sun.net.httpserver.HttpHandler; | ||
import com.sun.net.httpserver.HttpServer; | ||
import java.io.IOException; | ||
import java.io.OutputStream; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Code has been formatted wit spotless plugin. The plugin runs as part of the build and checks the formatting is consistent according. All contributions will have a single style - will make code easier to maintain. The style is google AOSP (Android OpenSource Project), adopted by many projects, good tooling support https://google.github.io/styleguide/javaguide.html . Formatting can be done via tooling and the plugin suggests that |
||
import java.io.ByteArrayOutputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.OutputStream; | ||
import java.net.InetSocketAddress; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
import com.sun.net.httpserver.Headers; | ||
|
||
import com.openfaas.model.*; | ||
|
||
public class App { | ||
|
||
|
@@ -56,15 +53,15 @@ public void handle(HttpExchange t) throws IOException { | |
} | ||
// StandardCharsets.UTF_8.name() > JDK 7 | ||
requestBody = result.toString("UTF-8"); | ||
} | ||
} | ||
|
||
// System.out.println(requestBody); | ||
Headers reqHeaders = t.getRequestHeaders(); | ||
Map<String, String> reqHeadersMap = new HashMap<String, String>(); | ||
|
||
for (Map.Entry<String, java.util.List<String>> header : reqHeaders.entrySet()) { | ||
java.util.List<String> headerValues = header.getValue(); | ||
if(headerValues.size() > 0) { | ||
if (headerValues.size() > 0) { | ||
reqHeadersMap.put(header.getKey(), headerValues.get(0)); | ||
} | ||
} | ||
|
@@ -73,20 +70,25 @@ public void handle(HttpExchange t) throws IOException { | |
// System.out.println("Req header " + entry.getKey() + " " + entry.getValue()); | ||
// } | ||
|
||
IRequest req = new Request(requestBody, reqHeadersMap,t.getRequestURI().getRawQuery(), t.getRequestURI().getPath()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No code has been changed. |
||
|
||
IRequest req = | ||
new Request( | ||
requestBody, | ||
reqHeadersMap, | ||
t.getRequestURI().getRawQuery(), | ||
t.getRequestURI().getPath()); | ||
|
||
IResponse res = this.handler.Handle(req); | ||
|
||
String response = res.getBody(); | ||
byte[] bytesOut = response.getBytes("UTF-8"); | ||
|
||
Headers responseHeaders = t.getResponseHeaders(); | ||
String contentType = res.getContentType(); | ||
if(contentType.length() > 0) { | ||
if (contentType.length() > 0) { | ||
responseHeaders.set("Content-Type", contentType); | ||
} | ||
|
||
for(Map.Entry<String, String> entry : res.getHeaders().entrySet()) { | ||
for (Map.Entry<String, String> entry : res.getHeaders().entrySet()) { | ||
responseHeaders.set(entry.getKey(), entry.getValue()); | ||
} | ||
|
||
|
@@ -96,8 +98,8 @@ public void handle(HttpExchange t) throws IOException { | |
os.write(bytesOut); | ||
os.close(); | ||
|
||
System.out.println("Request / " + Integer.toString(bytesOut.length) +" bytes written."); | ||
System.out.println( | ||
"Request / " + Integer.toString(bytesOut.length) + " bytes written."); | ||
} | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,31 @@ | ||
// Copyright (c) OpenFaaS Author(s) 2018. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
package com.openfaas.entrypoint; | ||
|
||
import java.util.ServiceLoader; | ||
import com.openfaas.model.*; | ||
import java.util.ServiceLoader; | ||
|
||
public class HandlerProvider { | ||
private static HandlerProvider provider; | ||
private ServiceLoader<AbstractHandler> loader; | ||
|
||
private HandlerProvider() { | ||
loader = ServiceLoader.load(AbstractHandler.class); | ||
} | ||
|
||
public static HandlerProvider getInstance() { | ||
if(provider == null) { | ||
if (provider == null) { | ||
provider = new HandlerProvider(); | ||
} | ||
return provider; | ||
} | ||
|
||
public AbstractHandler getHandler() { | ||
AbstractHandler service = loader.iterator().next(); | ||
if(service != null) { | ||
if (service != null) { | ||
return service; | ||
} else { | ||
throw new java.util.NoSuchElementException( | ||
"No implementation for HandlerProvider"); | ||
throw new java.util.NoSuchElementException("No implementation for HandlerProvider"); | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alexellis : We don't need to setup these inside a
buildscript
.One way of configuring common options is to use
allprojects
andsubprojects
.https://docs.gradle.org/current/dsl/org.gradle.api.Project.html#org.gradle.api.Project:allprojects(groovy.lang.Closure)