spring cloud how to set encrypt.key property - spring

I work with spring cloud and I want to set encrypt.key property.
My application has bootstrap.yml but I don't have bootstrap.properties.
How can I set encrypt.key?
I get
{
"description": "The encryption algorithm is not strong enough",
"status": "INVALID"
}
when I executed localhost:8888/encrypt

Simply put encrypt.key=keyName in you bootstrap.yml or bootstrap.properties file to avoid the error
{"description": "The encryption algorithm is not strong enough", "status": "INVALID" }
while running config server locally.

Related

Accessing VCAP properties on PCF Spring Boot app

I have a simple Spring Boot app running on PCF. I am wondering if there is a better way to access VCAP environment variables from PCF. Specifically, I am trying to access service credentials for a RabbitMQ service instance running on PCF and bound to my application.
At the moment, I access the credentials using System.getenv:
JSONObject vcapServices = new JSONObject(System.getenv("VCAP_SERVICES"));
JSONArray rabbitmq = (JSONArray) vcapServices.get("p-rabbitmq");
JSONObject serviceInfo = (JSONObject) rabbitmq.get(0);
JSONObject credentials = (JSONObject) serviceInfo.get("credentials");
hostname = credentials.getString("hostname");
virtualHost = credentials.getString("vhost");
username = credentials.getString("username");
password = credentials.getString("password");
I was trying to get it working with the #Value annotation to try to access the VCAP environment variables like this:
#Value("${vcap.services.p-rabbitmq.credentials.hostname}")
private String hostname;
but I haven't been able to grab the values yet.
Is there any way I can access VCAP variables via the #Value annotation? Or is there a better way other than System.getenv to get these credentials from PCF once I deploy my application?
Is there any way I can access VCAP variables via the #Value annotation?
Yes, I think you need to change your format slightly. It's vcap.services.<service-instance-name>.credentials.hostname. You have the name of the service provider itself, not the name of your service instance. I can't see that name in the example above, but I've found the Javadoc to be helpful. It lists the following example.
VCAP_SERVICES: {
"rds-mysql-1.0": [
{
"credentials": {
"host": "mysql-service-public.clqg2e2w3ecf.us-east-1.rds.amazonaws.com",
"hostname": "mysql-service-public.clqg2e2w3ecf.us-east-1.rds.amazonaws.com",
"name": "d04fb13d27d964c62b267bbba1cffb9da",
"password": "pxLsGVpsC9A5S",
"port": 3306,
"user": "urpRuqTf8Cpe6",
"username": "urpRuqTf8Cpe6"
},
"label": "rds-mysql-1.0",
"name": "mysql",
"plan": "10mb"
}
]
}
In this example, the service provider name is "rds-mysql-1.0", which would be the same as "p-rabbitmq" in your example. It then has a service instance name of "mysql" & that is what you'd use in your property placeholder.
Ex: vcap.services.mysql.credentials.host
https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/cloud/CloudFoundryVcapEnvironmentPostProcessor.html
Having explained all that, it can still be a fair bit of work to wire up all of your properties. Especially if you're utilizing multiple services or in your case, you're using RabbitMQ which has a lot of info that is passed through VCAP_SERVICES.
UPDATE
Spring Cloud Connectors is still an option, leaving it below for historical context, but java-cfenv is the recommended way to access service properties going forward. It plays nicer with Spring Boot and is every bit as capable.
DEPRECATED
Another option to consider is Spring Cloud Connectors. This is a library that will basically handle all of this for you. You ask for a DataSource or ConnectionFactory and it makes sure one is wired into your application.
Ex:
#Bean
public RabbitConnectionFactory rabbitFactory() {
return connectionFactory().rabbitConnectionFactory();
}
See Getting Started if you're interested in checking this out.

Forward hostname and path in proxy

I have an external service:
https://domainx.com/path/a/to/my/app
Via proxies and webservices it ends-up in my Spring (Data Rest) application on a tomcat server, exposed under:
http://mytomcatserver:8080/this/is/my/app
This app returns a HAL-JSON response with in it a _links section, pointing to itself and other resources. For example:
{
"id": "a_resource_001",
"_links": {
"self": {
"href": "http://mytomcatserver:8080/this/is/my/app/res/a_resource_001"
}
}
}
On the consuming side this link won't mean anything of course.
This was solved: on the consuming side, somewhere a header is added:
X-Forwarded-Host=domainx.com
Then the result became (automatically thanks to the framework):
{
"id": "a_resource_001",
"_links": {
"self": {
"href": "https://domainx.com/this/is/my/app/res/a_resource_001"
}
}
}
The link is improved, but still the path / context-root doesn't match:
/path/a/to/my/app != /this/is/my/app.
So, I thought, is there a X-Forwarded-Path or something like that. Some header that is picked up by my application framework (Tomcat, or Spring, or Spring Data Rest) and used to build the url in the JSON response.
But no, didn't find it.
Does somebody know how to solve such issues. It seems to me I'm not the first dealing with this stuff.
O yeah, using the same path is not an option in this case. (Of course, if I would expose my application's context-root as /path/to/my/app, it would work. not an option in this case)
I imagine there is a solution in Tomcat/Spring where some headers might influence the links.
But I also think that this can be solved in the web-server (apache) or proxy settings.
I had same issues with this.
While you're using a spring application, the easiest way is to set the context path the same to the proxy.
There is also the option to get the x-forwarded-for information. Those has to be sent from proxy.
On application side you can use (in this case application.properties)
server.use-forward-headers=true
server.servlet.context-path=/my/custom/context/path

How to set build path configuration in spring boot webapp

I am in new to spring boot. I have created a web app using spring boot. My application require some properties file to do the processing. In eclipse What I do i set the path on Run configuration like bellow.
Now When I run the application I gets the require file on path and run smoothly.
Now I want to deploy the war file on some server. How do i provide this path to my application.
Bellow is the project structure of my project. and files are here
highlighted
How do I set this file path using application.properties or any other way so that, I don't have to provide the path from run configuration, and the .war can be deploy on any server.
Update 1 : This what I tried.
Created a customStart.bat
content of the file is
set CATALINA_OPTS="-engine.home="/src/main/resources/" -Dlog4j.configuration=config/log4j.xml -Dlog4j.debug=true"
call startup.bat %CATALINA_OPTS%
But still that argument is not set. How do I do that?
As an option you can add your properties to %tomcat_home%\conf\catalina.properties
Just put them at the end of the file as follows:
log4j.configuration=config/log4j.xml
.....
From spring boot official documentation (This is a highlight of the concept of creating custom spring boot variable) bellow you'll find a link to a Q/A that describes the solution.
Spring Boot jars are shipped with meta-data files that provide details
of all supported configuration properties. The files are designed to
allow IDE developers to offer contextual help and “code completion” as
users are working with application.properties or application.yml
files.
The majority of the meta-data file is generated automatically at
compile time by processing all items annotated with
#ConfigurationProperties. However, it is possible to write part of the
meta-data manually for corner cases or more advanced use cases.
Configuration meta-data files are located inside jars under
META-INF/spring-configuration-metadata.json They use a simple JSON
format with items categorized under either “groups” or “properties”
and additional values hint categorized under "hints":
Here is an example of a meta data config file :
{"groups": [
{
"name": "server",
"type": "org.springframework.boot.autoconfigure.web.ServerProperties",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
},
{
"name": "spring.jpa.hibernate",
"type": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties$Hibernate",
"sourceType": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties",
"sourceMethod": "getHibernate()"
}
...
],"properties": [
{
"name": "server.port",
"type": "java.lang.Integer",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
},
{
"name": "spring.jpa.hibernate.ddl-auto",
"type": "java.lang.String",
"description": "DDL mode. This is actually a shortcut for the \"hibernate.hbm2ddl.auto\" property.",
"sourceType": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties$Hibernate"
}
...
],"hints": [
{
"name": "spring.jpa.hibernate.ddl-auto",
"values": [
{
"value": "none",
"description": "Disable DDL handling."
},
{
"value": "validate",
"description": "Validate the schema, make no changes to the database."
},
{
"value": "update",
"description": "Update the schema if necessary."
},
{
"value": "create",
"description": "Create the schema and destroy previous data."
},
{
"value": "create-drop",
"description": "Create and then destroy the schema at the end of the session."
}
]
}
]}
Each “property” is a configuration item that the user specifies with a
given value. For example server.port and server.servlet-path might be
specified in application.properties as follows:
server.port=9090 server.servlet-path=/home The “groups” are higher
level items that don’t themselves specify a value, but instead provide
a contextual grouping for properties. For example the server.port and
server.servlet-path properties are part of the server group.
Notes:
The groups section is note required
“hints” are additional information used to assist the user in configuring a given property. When configuring the spring.jpa.hibernate.ddl-auto property, a tool can use it to offer some auto-completion help for the none, validate, update, create and create-drop values.
You can easily generate your own configuration meta-data file from
items annotated with #ConfigurationProperties by using the
spring-boot-configuration-processor jar
You can check this Q/A
** for more details check the spring boot apendix section **

How to store application.properites values using manifest.yml to contain passwords?

So my application.properties would look like:
spring.datasource.url=jdbc:sqlserver://localhost:1433;databaseName=mydb
spring.datasource.username=user
spring.datasource.password=123456
spring.jpa.database-platform=org.hibernate.dialect.SQLServer2012Dialect
I don't want others to be able to see my user and password when they go into my application.properties file.
Is there an alternative way to push values to cloud foundry? Something like manifest.yml?
Attempt to create manifest.yml
I tried to make a manifest file so I can bind it with my application on cloud foundry.
VCAP_SERVICES =
{
"oraclesql": [
{
"name": "OrcaleDb",
"label": "oraclesql",
"tags": [
"oracledb",
"oracle",
"relational"
],
"plan": "free",
"credentials": {
"uri": "jdbc:sqlserver://localhost:1433;databaseName=mydb",
"username": "user",
"password": "123456"
}
}
]
}
Created application.yml
//this works
spring:
application:
name: tester
datasource:
driverClassName: jdbc:sqlserver://localhost:1433;databaseName=mydb
username: user
password: 123456
initialize: false
jpa:
databasePlatform: org.hiberate.dialect.Oracle10gDialect
Yes and no. Unfortunately the manifest.yml doesn't work quite like that. The file provides the settings that will be used for cf push. It's application agnostic and doesn't know anything about Spring, Java, your programming language or your application framework of choice. Thus it cannot make changes to your application.properties file or other framework specific configuration.
Fortunately, there are many ways to configure Spring Boot (see here) and one of them is via environment variables. What's fortunate about this is that you can set environment variables via manifest.yml. Thus if you set the proper environment variables in manifest.yml, you can configure your application.
For reference, here are instructions for setting env variables in manifest.yml.
https://docs.cloudfoundry.org/devguide/deploy-apps/manifest.html#env-block
It looks roughly like this:
---
...
env:
ENV_1: val_1
ENV_2: val_2
Spring Boot will map environment variables to properties using the rules explained here. A basic example would be SPRING_DATASOURCE_USERNAME maps to spring.datasource.username in application.properties.
What you actually want to do here is have your database connection as a cloud foundry service rather than defined in your application.properties. As Daniel's answer suggests, Spring can pick up ENV variables, but setting connection details in the manifest is not the idiomatic way to do this.
By having a service, the connection details are stored in the VCAP_SERVICES variable when bound to the application - spring can read from there. The spring-music app shows the prototypical way of doing this.

Spring Boot Actuator Cannot Show diskSpace Information

I have two Spring Boot application. I've added Spring Boot Actuator both of them. When I run one of them I can see diskSpace:
{
"status": "UP",
"diskSpace": {
"status": "UP",
"total": 399055067136,
"free": 346446485504,
"threshold": 10485760
}
}
However at other service I can only see:
{
"status": "UP"
}
Even I add that property to second service:
management:
health:
diskspace:
enabled: true
I still cannot see diskSpace information. When I debug the system I see that such properties are collected but not returned to UI. What can be the problem?
Because only ADMINs are authorized to see any more info than this
{
"status": "UP"
}
To see all the metrics, authenticate with any user who has a spring security role ADMIN.
Or
(less preferable option)
Disable security for actuator endpoint like this
in application properties yaml file
management:
security:
enabled: false
In case if you are using spring security which is by default ON for actuator endpoints, you can disable it in your yml file -
management:
security:
enabled: false
management.security.enabled is deprecated now.
You can get full health details by adding a line in application.properties:
management.endpoint.health.show-details=always
Just add a line in application.properties:
management.endpoint.health.show-details = always
this made health show details to all users other than authorized people.
Spring boot actuator's HealthIndicator checks available disk space and reports a status of Status#DOWN when it drops below a configurable threshold.
so in your case for the second application the free space available is more than the threshold hence hou don't see any thing being reported.
you probably can debug and see in your code the values free disk space and the threshold.
let me know if this make sense...

Resources