Spring Config Server - resolvePlaceholders + enviroment variables - java

I've got question about resolving environment variables in shared files of config server.
My current setup is pretty minimal :
src/main/resources/shared/application.yml :
application:
version: 0.0.1-early
test: ${JAVA_HOME}
src/main/resources/application.properties :
spring.profiles.active=native
spring.cloud.config.server.native.searchLocations=classpath:/shared
Using gradle with :
spring-boot-gradle-plugin:2.0.0.RELEASE
spring-cloud-dependencies:Camden.SR7
And then of course compile 'org.springframework.cloud:spring-cloud-config-server' in deps
Problem :
GET http://localhost:8888/apptest/application gives me :
{
"name": "apptest",
"profiles": [
"application"
],
"label": null,
"version": null,
"state": null,
"propertySources": [
{
"name": "classpath:/shared/application.yml",
"source": {
"application.version": "0.0.1-early",
"application.test": "${JAVA_HOME}"
}
}
]
}
So env variable is not resolved. Same thing is with :
http://localhost:8888/apptest/application?resolvePlaceholders=true
http://localhost:8888/lab/apptest-application.properties?resolvePlaceholders=true
http://localhost:8888/lab/apptest-application.properties?resolvePlaceholders=false
http://localhost:8888/apptest-application.properties?resolvePlaceholders=true
I've looked at Spring cloud config server. Environment variables in properties but solution didn't help me + there where few new versions since then. So I'm opening new question.

Actually it's not a bug and everything is fine. I did not understood how Config server works.
http://localhost:8888/apptest/application - returns yet not resolved value of ${JAVA_HOME}
When we get ei. into container "C" that pings Config Service for configuration and do curl http://config:8888/apptest/application we get the same - unresolved ${JAVA_HOME}
But when we look into Spring application ei. in container "C" and try to inject #Value("${application.test}") somewhere, we get proper value or info that env variable was not set.
It means that environment variables are resolved on client side.
Thanks to that I've understood how NOT production ready env_variables approach is.

Well the changes happened here https://github.com/spring-cloud/spring-cloud-config/commit/f8fc4e19375d3b4c0c2562a71bc49ba288197100 that removes the support of replacing the environment variables.
You can always add a new controller and override the behaviour of the EnvironmentPropertySource#prepareEnvironment

Related

How to: generate .so file using rules_go in bazel on windows

I've switched (or, am in the process of switching) to using bazel, though I'm doing so on Windows.
I'm interested in calling into my Go code from Java, so I started with this tutorial.
I was able to make that work using the same code as on their Github example and everything works fine. I tried adapting that to my bazel build. If I take the awesome.so file generated by go build -o awesome.so -buildmode=c-shared awesome.go and include it as a resource to my java_library, I can make everything work.
Relevant files shown below.
Ideally, however, I'd like to have everything generated through bazel, but despite all my attempts thus far my go_binary rule always outputs awesome.a (and awesome.x). If I switch to using //go:awesome as the resource from java:client_lib I am able to successfully see the awesome.a output as a resource, which suggests that getting my go_binary to output awesome.so is the last piece of the puzzle, but the correct combination of flags has thus far eluded me.
Basically I just want to make my go_binary rule have the same behavior as running go build -o awesome.so --buildmode=c-shared awesome.go.
In theory I'm ok if I need another rule to bridge the gap, but since I'm on windows and bash has been hit or miss thus far, using genrule as the intermediate doesn't currently look promising.
Please advise, and thanks!
WORKSPACE
...
# bazelbuild/rules_go for golang support.
http_archive(
name = "io_bazel_rules_go",
sha256 = "b725e6497741d7fc2d55fcc29a276627d10e43fa5d0bb692692890ae30d98d00",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.24.3/rules_go-v0.24.3.tar.gz",
"https://github.com/bazelbuild/rules_go/releases/download/v0.24.3/rules_go-v0.24.3.tar.gz",
],
)
load("#io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
go_rules_dependencies()
go_register_toolchains()
...
go/awesome.go is copied from the article.
go/BUILD
load("#io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
package(default_visibility = ["//visibility:public"])
go_binary(
name = "awesome",
srcs = glob(["*.go"]),
cgo = True,
copts = [
"-fPIC", # I tried adding this after some other reading about .a->.so
],
gc_linkopts = [
"-shared", # I think this is equivalent to the linkmode=c-shared below, but... <shrug>
],
linkmode = "c-shared",
static = "off",
)
# This one uses the pre-built awesome.so, and this works.
filegroup(
name = "prebuilt_awesome_resource",
srcs = ["awesome.so"],
)
java/Client.java is copied from the github repo linked in the article (with slight tweaks to the library's location).
java/BUILD
package(default_visibility = ["//visibility:public"])
java_import(
name = "jna",
jars = ["jna.jar"],
)
java_library(
name = "client_lib",
srcs = glob(["*.java"]),
resources = [
# "//go:awesome", # I'd rather use this one.
"//go:prebuilt_awesome_resource",
],
deps = [
":jna",
],
)
java_binary(
name = "client",
main_class = "Client",
runtime_deps = [
":client_lib",
],
)
and also, since it was important getting go stuff to run:
%programdata%/basel.bazelrc
startup --output_user_root="C:/_bazel_out"
build --compiler=mingw-gcc
Well, I guess I need to go sit in the shame cube for a while.
Of all the options I was looking at for the compiler I missed checking other attributes on go_binary. Specifically, the obvious one, out. The one that actually corresponds to the -o flag on go build
I added out = "awesome.so" to my go_binary rule and, sure enough, everything works.
Well that's a few hours wasted. Thanks Jay for trying to help and sorry for asking a dumb question.
This might not answer your question exactly, but I can give an example of calling a Go shared library from a C program on macOS. Hopefully that gets you most of the way there.
For the go_binary, you just need linkmode = "c-shared". You'll also need cgo = True for each package that either contains cgo code or has exported definitions. You don't need -shared, -fPIC, or static = "off".
Exported definitions should be marked with an //export comment.
There's an implicitly declared target with the suffix .c_hdrs that builds a header file for the Go library. It's :go_hello.c_hdrs in the example below. The actual header file name is go_hello.h, matching the target name.
You need to wrap the generated files with a cc_import rule to make it usable as a C/C++ dependency. #2433 is an open issue to streamline that process, but it's only recently possible in Bazel.
Anything that can consume a cc_library can consume the cc_import target the same way. So you should be able to call Go functions via JNI, though I've never tried that out.
BUILD.bazel
load("#io_bazel_rules_go//go:def.bzl", "go_binary")
go_binary(
name = "go_hello",
srcs = ["hello.go"],
cgo = True,
linkmode = "c-shared",
)
cc_import(
name = "c_hello",
hdrs = [":go_hello.c_hdrs"],
shared_library = ":go_hello",
)
cc_binary(
name = "use",
srcs = ["use.c"],
deps = [":c_hello"],
)
hello.go
package main
import "fmt"
import "C"
//export SayHello
func SayHello() {
fmt.Println("hello")
}
func main() {}
use.c
#include "go_hello.h"
int main() {
SayHello();
return 0;
}

Parse Swagger with refs inside jar with openapi4j

I'm trying to parse the following swagger file with openapi4j:
{
"openapi" : "3.0.0",
"info" : {
"title" : "My Service",
"version" : "1.0.0"
},
"paths" : {
"/endpoint" : { "$ref" : "swagger2.json#/paths/get_endpoint" },
}
}
You can see it has a simple ref to another file within the same folder.
I parse the Swagger file with the following:
URL url = Thread.currentThread().getContextClassLoader().getResource(filePath);
openAPI = new OpenApi3Parser().parse(url, false);
Locally in my IDE, this works great. The ref is loaded and I am able to validate requests against it with no issues. However, when I jar up the project, it is able to load the initial swagger file fine, but none of the refs. I get the following error:
StackTrace: org.openapi4j.core.exception.ResolutionException: Failed to load document from 'swagger2.json'
at org.openapi4j.core.model.reference.AbstractReferenceResolver.registerDocument(AbstractReferenceResolver.java:118)
at org.openapi4j.core.model.reference.AbstractReferenceResolver.findReferences(AbstractReferenceResolver.java:92)
at org.openapi4j.core.model.reference.AbstractReferenceResolver.resolve(AbstractReferenceResolver.java:53)
at org.openapi4j.core.model.v3.OAI3Context.resolveReferences(OAI3Context.java:103)
at org.openapi4j.core.model.v3.OAI3Context.<init>(OAI3Context.java:73)
at org.openapi4j.core.model.v3.OAI3Context.<init>(OAI3Context.java:47)
at org.openapi4j.parser.OpenApi3Parser.parse(OpenApi3Parser.java:34)
at org.openapi4j.parser.OpenApi3Parser.parse(OpenApi3Parser.java:18)
at org.openapi4j.parser.OpenApiParser.parse(OpenApiParser.java:53)
I'm not sure if this is possible. I assume I may have to copy my project resources out at runtime to the filesystem somewhere to be accessed more easily. I would like to avoid that route if possible.
Turns out this was a bug in openapi4j, which was resolving refs with URI instead of URL. This has been fixed in 0.9

Java: Where is Autowired.Value looking for a setting?

I've inherited a large-ish Java project using org.springframework.beans.factory.annotation.Autowired, among other things.
I have one module that starts like this:
#Autowired
public Application(
FlattenByFeedRunInvoker flattenRunInvoker,
#Value("${jobId:}") String jobId,
#Value("${instanceId:}") String instanceId,
#Value("${feed}") String feed,
When I run it under debug, using this config:
{
"type": "java",
"name": "Debug (Launch)-Application<tbsm-reporting-etl-flatten>",
"request": "launch",
"mainClass": "com.tbsm.reporting.etl.flatten.Application",
"projectName": "tbsm-reporting-etl-flatten"
}
I get the message:
[ERROR] 2019-07-23 10:10:58.137 [THREAD ID=main]
[CLASS=(SpringApplication:771)] - Application startup failed
java.lang.IllegalArgumentException: Could not resolve placeholder
'feed' in value "${feed}"
I'm guessing that the framework is trying to find a value labelled "feed" somewhere. FWIW I do have a file called "default.properties" in the "resources" directory for the project and that file has the line
feed=myfeed
It looks like that file or value is not being found. I'm wondering if it is just in the wrong directory wrt the program i'm running:
..\src\main\java\com\tbsm\reporting\etl\flatten\Application.java
vs
..src\main\resources\default.properties
Or if I need to do something else to tell it where to look. e.g. does the vscode launch config need something else?

Jenkins Java: Get user who started the build

Under http://[JENKINS_NAME]/job/[JOB_NAME]/[BUILD_NUMBER]/
I can see Started by user [USER_NAME].
I want to get that username from my java application.
Any help is much appreciated.
You can make a http call to get all these details. URL to get those details is:
http://<Jenkins URL>/job/<job name>/<build number>/api/json
After the rest call, you will be getting this json.
{
"_class": "hudson.model.FreeStyleBuild",
"actions": [
{
"_class": "hudson.model.CauseAction",
"causes": [
{
"_class": "hudson.model.Cause$UserIdCause",
"shortDescription": "Started by user XXXXXX",
"userId": "xxx#yyy.com",
"userName": "ZZZZZZZZ"
}
]
},
{},
{
"_class": "jenkins.metrics.impl.TimeInQueueAction"
},
{},
{}
],
...
}
So All you have do is parse this json and get the value under javavar['actions'][0]['causes'][0]['userName']. Definitely it will be like that only. I maynot be sure about the indexes. You just try and figure out. Hope this helps.
Mostly for every page in the jenkins instance, you will be having REST API link. Please click on it to see the rest api url and its output for that url.
You could get the build user from Jenkins environment (i.e as an env var). If you use Jenkins 2 pipeline, For example:
pipeline {
//rest of the pipeline
stages {
stage('Build Info') {
steps {
wrap([$class: 'BuildUser']) {
sh 'java -jar <your_java_app>.jar'
}
}
}
}
In your java app you should be able to get the environment variable using System.getenv("BUILD_USER") or else you could pass it as a JVM arg. Ex: sh 'java -jar -DbuildUser=$BUILD_USER <your_java_app>.jar' and get the buildUser system property in the application.
On older version of Jenkins, you may use Build User Vars Plugin or Env Inject plugin. As in the answers on this question. how to get the BUILD_USER in Jenkins when job triggered by timer

Errror when packaging sencha touch for ios debug

I'm trying to package a sencha application for ios. But when I in the terminal do: "sencha package build package.json" I get the following
: [ERR] null
at com.sencha.command.environment.AppEnvironment.(AppEnvironment.java:48)
at com.sencha.command.environment.BuildEnvironment.load(BuildEnvironment.java:193)
at com.sencha.command.Sencha.loadBuildEnvironment(Sencha.java:374)
at com.sencha.command.Sencha.main(Sencha.java:127)
I probably screwed something up with the certficates and provisioning profiles, but, I'm not sure if this is some kind of environment error, ie sencha cmd not finding path of Java. The error seems to suggest this, but the cmd works with other commands. I can, for example, create a new app with "sencha app generate myapp ..myapp".
So, my question is really, is the error caused by some environment problem, and if so, what to do about it, or is his a problem related to some errror in my packager.json. Here's my packager.json file.
All help much appreciated!
{
"applicationName":"app",
"applicationId":"com.appname",
"bundleSeedId":"xxxxxxxx",
"versionString":"1.0",
"iconName":"icon.png",
"icon": {
"36":"resources/icons/Icon_Android36.png",
"48":"resources/icons/Icon_Android48.png",
"57":"resources/icons/Icon.png",
"72":"resources/icons/Icon~ipad.png",
"114":"resources/icons/Icon#2x.png",
"144":"resources/icons/Icon~ipad#2x.png"
},
"inputPath":"/Applications/XAMPP/xamppfiles/htdocs/app/",
"outputPath":"../build/",
"configuration":"Debug",
"platform":"iOS",
"deviceType":"Universal",
"certificatePath":"../cert/mycert.p12",
"certificateAlias":"iPhone Developer:",
"certificatePassword":"",
"provisionProfile":"../cert/name.mobileprovision",
"notificationConfiguration":"",
"orientations": [
"portrait",
"landscapeLeft",
"landscapeRight",
"portraitUpsideDown"
]
}

Categories