xs-app.json/routes/0: Format validation failed (Route references unknown destination "service-destination") - s4sdk

trying to install the approuter currently, following this tutorial:
https://blogs.sap.com/2017/07/18/step-7-with-sap-s4hana-cloud-sdk-secure-your-application-on-sap-cloud-platform-cloudfoundry/
When pushing the approuter to CF, I get an destination error:
xs-app.json/routes/0: Format validation failed (Route references unknown destination "service-destination")
This is my manifest.yml:
---
applications:
- name: xyz
command: 'node approuter/approuter.js'
host: xyz-93deb1cd-7b72-4060-94e7-21342342
path: approuter
memory: 128M
buildpack: https://github.com/cloudfoundry/nodejs-buildpack
env:
TENANT_HOST_PATTERN: 'xyz(.*).cfapps.eu10.hana.ondemand.com'
destinations: "[{"name":"service-destination", "url": "https://gfuowbasdatq19agtuthorizations-srv.cfapps.eu10.hana.ondemand.com", "forwardAuthToken": true}]"
SAP_JWT_TRUST_ACL: '[{"clientid" : "*", "identityzone" : "*"}]'
services:
- my-xsuaa
- service-destination
This is my xs-app.json:
{
"routes": [{
"source": "/",
"target": "/",
"destination": "service-destination"
}]
}
Where is the application actually searching for this destination? I created it in my CF-account as well, pointing to my service-url.

In YAML (as well as many other markup languages, e.g. JSON) double quotes inside double quotes need to be escaped. (Cf. the YAML spec section 7.3.1 and this blog post)
So for you there are two options for your destinations variable:
1. Replacing all " inside with \" (relatively cumbersome, especially if you want to change the destinations in the future)
2. Use single quotes as boundaries. So the value of your destinations variable would look like this:
'[{"name":"service-destination", "url": "https://gfuowbasdatq19agtuthorizations-srv.cfapps.eu10.hana.ondemand.com", "forwardAuthToken": true}]'

Related

Adding IoT rule with an error action through cloudformation yaml

I am trying to add an iot rule with error action using following cloudformation yaml file
extract from yaml:
DaIoTRule:
Type: AWS::IoT::TopicRule
Properties:
RuleName: sda
TopicRulePayload:
RuleDisabled: false
Sql: SELECT *, topic(2) AS source FROM 'topic/sensors/+'
Actions:
- Lambda:
FunctionArn: !GetAtt LambdaFunction.Arn
ErrorAction:
S3:
RoleArn: !GetAtt DAIoTRuleErrorActionIamRole.Arn
Bucket: iot-message-dump
Key: "errors/${topic()}/${timestamp()}"
But I keep getting this error:
{
"StackId": "arn:aws:cloudformation:us-east-1:961234632786:stack/wx-da-lambda/91423s00-4e97-11ea-aedd-0ee829hbc650",
"EventId": "DAIoTRule-CREATE_FAILED-2020-02-17T06:51:38.299Z",
"StackName": "da-lambda",
"LogicalResourceId": "DaIoTRule",
"PhysicalResourceId": "",
"ResourceType": "AWS::IoT::TopicRule",
"Timestamp": "2020-02-17T06:51:38.299Z",
"ResourceStatus": "CREATE_FAILED",
"ResourceStatusReason": "Encountered unsupported property bucket"
}
I created this yaml using https://docs.aws.amazon.com/iot/latest/developerguide/rule-error-handling.html as reference.
Can someone point me to what I am doing wrong ?
CloudFormation uses the BucketName property instead of Bucket for S3 actions (including error actions).
See https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iot-topicrule-s3action.html#cfn-iot-topicrule-s3action-bucketname

Externalise - spring cloud config server multiple git repo configuration

I am trying to set up a spring-cloud-config-server for production.
I want to read multiple git repos so I am providing following configuration in application.yml of config-server placed in src/main/resources
spring:
application:
name: config-server
profiles:
active: git
cloud:
config:
server:
git:
uri: https://somedomain.com/project1/project1.git
username: project1user
password: project1password
repos:
project2:
pattern: project2/*
uri: https://somedomain.com/project2/project2.git
username: project2user
password: project2password
searchPaths:
- 'src/main/resources'
Now, I want to externalize this configuration of the config server.
I could provide main git repo (https://somedomain.com/project1/project1.git) properties by environment variables like following
spring.cloud.config.server.git.uri=https://somedomain.com/project1/project1.git
spring.cloud.config.server.git.username=project1user
spring.cloud.config.server.git.password=project1password
But what about other git repo properties. Passing complex map-like structure would be pretty tedious if passed via environment variables.
What is the best possible way to pass this configuration of other repos?
Passing some configuration as an environment variable has other disadvantages like those properties could not be refreshed on runtime.
Is there any possibility that additional repo configuration is picked by from some configuration file in main git (https://somedomain.com/project1/project1.git) itself?
The Spring Cloud Config Server provides a configuration with multiples repositories and they can be accessed by url like we do for one git repo. The config server will fetch each configuration by a pattern, so your label {application} in the path will be the key to find the correct repository. Like in mine I did:
spring:
cloud:
config:
server:
git:
uri: https://github.com/solivaf/config-properties-foo
Now we should add our additional repositories as you can see below:
spring:
cloud:
config:
server:
git:
uri: https://github.com/solivaf/config-properties-foo
repos:
appFoo:
pattern: app-foo
uri: https://github.com/solivaf/config-properties-bar
Restart the config server and perform the requests below.
$ curl localhost:8080/fooapp/prod
{
"name": "fooapp",
"profiles": [
"prod"
],
"label": null,
"version": "8686fb74f9af0aead98bd20d6e20e84a37028781",
"state": null,
"propertySources": [
{
"name": "https://github.com/solivaf/config-properties-foo/application-prod.yml",
"source": {
"bar.foo": "testProdPropertiesYml"
}
},
{
"name": "https://github.com/solivaf/config-properties-foo/application.yml",
"source": {
"bar.foo": "testPropertiesYml"
}
}
]
}
Now we can see the repository used to application fooapp, as we don’t have any pattern mapped to this application, the config server will use the default app, now if we specify the pattern app-foo which is mapped in our config-server property file we should get another repository as response.
$ curl localhost:8080/app-foo/prod
{
"name": "app-foo",
"profiles": [
"prod"
],
"label": null,
"version": "f34ced0565042be4cf87c937c1dab2703e0b8ed2",
"state": null,
"propertySources": [
{
"name": "https://github.com/solivaf/config-properties-bar/app-foo-prod.yml",
"source": {
"foo.bar": "testProdPropertiesYml"
}
},
{
"name": "https://github.com/solivaf/config-properties-bar/application-prod.yml",
"source": {
"foo.bar": "testProdPropertiesYml"
}
},
{
"name": "https://github.com/solivaf/config-properties-bar/application.yml",
"source": {
"foo.bar": "testPropertiesYml"
}
}
]
}
Now, we have the correct repository which was mapped in our property file and all files which represents our app-foo application. The response order represents the hierarchy of the file being the most priority the first file in the list.

How to fetch properties from config-server consisting of more than one repo

I wanted to fetch properties from two git repos. one is https://username#bitbucket.my.domain.com/share.git - which will have a property file contains some common key value pair and the other one is https://username#bitbucket.my.domain.com/service.git - it will have property files of all the micro services.
While I am deploying the service only one yml file (which is in https://username#bitbucket.my.domain.com/share.git repo) is read by the config server. What I am missing? How to read the property file from another repo i.e. https://username#bitbucket.my.domain.com/service.git too?
I wanted to deploy the service in PCF. So I configured the config-server in PCF with the following json.
{
"count": 1,
"git": {
"label": "feature",
"uri": "https://username#bitbucket.my.domain.com/share.git",
"username": "username",
"password": "password",
"repos": {
"configserver": {
"password": "password",
"label": "feature",
"uri": "https://username#bitbucket.my.domain.com/service.git"
"username": "username"
}
}
}
}
Name of my service is LogDemo and spring profile is active. I have created two yml files and placed in the corresponding repo. (I have given same name two both the files like LogDemo-active.yml). While I am deploying the service only one yml file (which is in https://username#bitbucket.my.domain.com/share.git repo) is read by the config server. /env is giving me the following:
{
"profiles": [
"active",
"cloud"
],
"server.ports": {
"local.server.port": 8080
},
"configService:configClient": {
"config.client.version": "234e59d4a9f80f035f00fdf07e6f9f16e5560a55"
},
"configService:https://username#bitbucket.my.domain.com/share.git/LogDemo-active.yml": {
"key1": "value1",
"key2": "value2"
},
...................
...................
What I am missing? How to read the property file from other repo i.e. https://username#bitbucket.my.domain.com/service.git too?
Below is my bootstrap.yml
spring:
application:
name: LogDemo
mvc:
view:
prefix: /
suffix: .jsp
Here is my manifest file
---
inherit: baseManifest.yml
applications:
- name: LogDemo
host: LogDemo
env:
LOG_LEVEL: INFO
spring.profiles.active: active
TZ: America/New_York
memory: 1024M
domain: my.domain.com
services:
- config-server-comp
When using multiple repos, the repos that will be applied depend on the pattern's defined for those repos. The default pattern is <repo-name>/*. Thus changing the repo name to LogDemo will activate the repo for your app, because the app name, spring.application.name, is LogDemo.
If one or more patterns match, then the repo for the matched patterns will be used. If no pattern matches then the default is used.
Full details are described in the docs here.
https://cloud.spring.io/spring-cloud-config/single/spring-cloud-config.html#_pattern_matching_and_multiple_repositories
If you don't need or want the pattern matching feature, you can use the [composite backend](
https://docs.pivotal.io/spring-cloud-services/2-0/common/config-server/composite-backends.html). The composite backend allows you to define multiple Git repositories. See the first config example here.
https://docs.pivotal.io/spring-cloud-services/2-0/common/config-server/composite-backends.html#general-configuration

CloudFoundry manifest.yml with objects as env variables

so I am building a SpringBootApplication and I currently have the following settings in the yml:
my:
caller:
- id: someId
url: someUrl
context: someContext
- id: someId2
url: someUrl2
context: someContext2
So basically it's a list of objects (I've created a POJO which has the 3 fields). Those objects are represented as a List in another class which is a #Component and has a #ConfigurationProperties(prefix = "my") and the List of POJOs is with #NestedConfigurationproperty.
So far everything works perfectly, Spring constructs the objects from the application.yml and fills the List just fine, however I can't simulate this configuration in CloudFoundry. I'm using a different manifest.yml for cloudfoundry, and I'm trying to place this structure in the env part of the manifest but it's not working (Cloudfoundry ignores it).
It looks something like this:
env:
my:
caller:
- id: someId
url: someUrl
context: someContext
- id: someId2
url: someUrl2
context: someContext2
I know with simple lines it works (for example ev_my_caller_id) but that way I can construct only 1 object, not a whole list and I haven't found anything in the CloudFoundry doc on how to construct multiple objects from the manifest.
If anyone has any ideas I would be really grateful!
The env block of the Cloud Foundry cli's manifest.yml file has a specific format. You cannot use an arbitrary structure and expect it to work.
The format is:
env:
var_name_1: val_1
var_name_2: val_2
See docs for more details -> https://docs.cloudfoundry.org/devguide/deploy-apps/manifest.html#env-block
If you set the env variable with the correct name, you can use that to override certain values in Spring. Thanks to Spring Boot's external configuration support. Maybe that would be an option for you here.
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
Ex: MY_PROPERTY=1234 would override my.property in application.properties.
You could use the SPRING_APPLICATION_JSON environment variable mentioned in the Spring Boot external config link that Daniel provided.
In your case, that would like something like this:
env:
SPRING_APPLICATION_JSON: '{ "my": { "caller": [{ "id": "someId", "url": "someUrl", "context": "someContext" }, { "id": "someId2", "url": "someUrl2", "context": "someContext2" }]}}'
Not sure what you are trying to do, but you can try something like this:
env:
test: '{ whatever complex object/variables }'
e.g.
env:
test: '{ variable = value, variable2 = value2 }'

ECMA 262 regex "^/" does not match input string "https://domain.herokuapp.com"

I have deployed my play 2.4 API based project to heroku. On production the api is seen on /swagger but it also shows some error. On navigating through the error it shows the json.
{
schemaValidationMessages: [{
level: "error",
domain: "validation",
keyword: "pattern",
message: "ECMA 262 regex "^/" does not match input string "https://domain.herokuapp.com "",
schema: {
loadingURI: "#",
pointer: "/properties/basePath"
},
instance: {
pointer: "/basePath"
}
}]
}
The dependency I have added is
"io.swagger" %% "swagger-play2" % "1.5.2"
From play prod configuration, I have overrided swagger basepath in my procfile.
-Dswagger.api.basepath=https://domain.herokuapp.com
What could be the reason for the error and how can I remove it?
Thanks
I think that this is the host, the basePath is supposed to be "/". At least this solved it for me
"host" : "https://domain.herokuapp.com",
"basePath" : "/",

Resources