Skip to content

Common modules

Config

Spring Cloud Configuration service is provided.

Run the service in command line in folder jws/jws-config/

jws-config-service.exe --install

jws-config-service.exe --start (on Windows in administrator's terminal)

jws-config-service start(on Linux)

or

run-jws-config.exe (on Windows)

run-jws-config(on Linux)

**Default configuration **

common-config/application.properties
## You can set all settings here for all applications
eureka.client.serviceUrl.defaultZone=${EUREKA_URI:http://localhost:8761}/eureka/
eureka.client.enabled=true

spring.servlet.multipart.max-file-size=150MB
spring.servlet.multipart.max-request-size=150MB
##LOG config:
logging.level.root=${CXN_ROOT_LOG_LEVEL:INFO}
logging.level.com.chemaxon.webservices.license=${LICENSE_LOG_LEVEL:INFO}
##Communication settings of gateway:
ribbon.ReadTimeout=25000
ribbon.ConnectTimeout=3000

hystrix.command.default.execution.timeout.enabled=true
hystrix.threadpool.default.coreSize=10
hystrix.shareSecurityContext=true
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=60000
hystrix.threadpool.default.maxQueueSize=100
hystrix.threadpool.default.queueSizeRejectionThreshold=90
You can set up various timeouts in JChem MicroServices. We use the Spring Cloud Stack with solutions from Netflix. Ribbon load balancer is responsible for the communication between the services. You can set up its timeout settings with the ribbon prefix, like: ribbon.ReadTimeout. This property controls when to interrupt waiting for an answer between Chemaxon services. You can also setup a guard with Hystrix circuit breaker with properties like: execution.isolation.thread.timeoutInMilliseconds which will interrupt your request if it does not get an answer during the timeout.
##DB config:
initOnStart=${DB_INIT_ON_START:AUTO}
updateMode=${DB_UPDATE_MODE:EXIT}

search.wallTimeLimitSeconds=${SEARCH_TIME_LIMT:3600}

com.chemaxon.zetor.settings.scheme=${CXN_SCHEME:GCRDB}
com.chemaxon.zetor.settings.indexDir=${CXN_STRUCTURE_DATA_DIR:./data/chemical-data/store}
com.chemaxon.zetor.settings.gcrdb.isSingleTable=${CXN_DB_LOGIC_SINGLE_TABLE:true}
com.chemaxon.zetor.settings.gcrdb.singleTableName=${CXN_DB_TABLE_NAME:engine_data}
com.chemaxon.zetor.settings.gcrdb.sqlBuilderProvider=${CXN_DB_DIALECT:H2}
com.chemaxon.zetor.settings.gcrdb.jdbcUrl=${CXN_DB_JDBC_URL:jdbc:h2:nio:${com.chemaxon.zetor.settings.indexDir}/db;COMPRESS=true}
com.chemaxon.zetor.settings.gcrdb.user=${CXN_DB_JDBC_USER:user}
com.chemaxon.zetor.settings.gcrdb.password=${CXN_DB_JDBC_PASSWORD:password}
com.chemaxon.zetor.settings.gcrdb.allowBatchUpdates=${CXN_DB_LOGIC_BATCH_UPDATE:true}
com.chemaxon.zetor.settings.forcePurge=true

com.chemaxon.webservices.db.import_export.dir=${CXN_DB_IMPORT_EXPORT_DIR:data/export}
com.chemaxon.webservices.db.import_export.importBatchSize=${CXN_DB_IMPORT_EXPORT_BATCH_SIZE:5000}

com.chemaxon.zetor.types[0].version=1
com.chemaxon.zetor.types[0].typeName=sample
com.chemaxon.zetor.types[0].typeId=1
com.chemaxon.zetor.types[0].tautomerHandlingMode=OFF
com.chemaxon.zetor.types[0].stereoAssumption=ABSOLUTE
com.chemaxon.zetor.types[0].standardizerConfig=aromatize

com.chemaxon.zetor.types[1].version=1
com.chemaxon.zetor.types[1].typeName=taumol
com.chemaxon.zetor.types[1].typeId=2
com.chemaxon.zetor.types[1].tautomerHandlingMode=GENERIC
com.chemaxon.zetor.types[1].stereoAssumption=ABSOLUTE
com.chemaxon.zetor.types[1].standardizerConfig=aromatize
If DB Web Services are run as part of a microservices system, specify here its configuration parameters.

If DB Web Services are run as standalone web application, specify its configurations in its own module's application.properties file.

See explanations here

Configuration using table instead of the common-config/application.properties file How to use JWS-CONFIG with JDBC backend.

  • Copy the right JDBC driver to 'extra-libs' folder.
  • In jws-config/config/application.properties set the followings:
1
2
3
4
5
6
7
8
9
spring.profiles.active=jdbc

spring.datasource.url=<jdbc url>

spring.datasource.driver-class-name=<jdbc driver class name>

spring.datasource.username=<username of jdbc connection>

spring.datasource.password=<password of jdbc connection>

more on Spring data source settings: https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#data-properties

This setting will only work if you have a table, called: PROPERTIES with this 5 text fields (these fields can be any text fields):

  • APPLICATION
  • PROFILE
  • LABEL
  • KEY
  • VALUE

example properties table creation SQL:

1
2
3
4
5
6
7
 CREATE TABLE PROPERTIES (

 APPLICATION VARCHAR(255) DEFAULT 'application',

 PROFILE VARCHAR(255) DEFAULT 'default',

 LABEL VARCHAR(255) DEFAULT 'master',KEY VARCHAR(255) NOT NULL,VALUE CLOB);

It is possible to use a different table than properties. In this case you have to set the QUERY to get key-value pairs, like:

spring.cloud.config.server.jdbc.sql=SELECT MY_PROPS.K AS KEY, MY_PROPS.V AS VALUE FROM MY_PROPS WHERE APP=? AND PROF=? and LBL=?

What are the defaults in the example SQL?

Spring Cloud Config is designed to provide properties from git repositories. This database schema mimics that. In the git repository all application can have their own settings in their application_name.properties file, or common properties can be in application.properties file. The default value 'application' in the APPLICATION column means it is "found" in application.properties file so it is distributed to all applications.

Every properties file can be linked to a specific profile, like: production, development, aws, etc. and their settings are only taken into account if their profile is active. The default value 'default' in PROFILE column means this setting is not paired to any specific profile name, but to the default profile.

Since in the original concept the configuration distribution is solved by git repositories, all files are also part of a git branch. The branch currently checked out is represented in the LABEL column, with default value 'master' it is mimicking to be part of the master branch. Here basically any value different from NULL is acceptable.

In the KEY column the keys should be set with the Properties syntax, so a simple property, like:

a.b.c=value

should be a.b.c

so for

**{yml} **

users:

1
2
3
4
5
a:

 b:

 c: value

it is also transleted to a.b.c;

Example with lists:

properties:

1
2
3
4
5
6
7
prop.path.list[0].a_key=a0_value

prop.path.list[0].b_key=b0_value

prop.path.list[1].a_key=a1_value

prop.path.list[1].b_key=b1_value

yml:

prop:

 path:

 list:

 - a_key: a0_value

 b_key: b0_value

 - a_key: a1_value

 b_key: b1_value

would translate to this insert sql (if the defaults are as in the example table creation SQL):

 INSERT INTO PROPERTIES (KEY, VALUE) VALUES ('prop.path.list[0].a_key', 'a0_value'), ('prop.path.list[0].b_key', 'b0_value'), ('prop.path.list[1].a_key', 'a1_value'), ('prop.path.list[1].b_key', 'b1_value');
**config/application.properties **
server.port=8888
logging.file.name=../logs/jws-config.log
eureka.client.enabled=true
spring.profiles.active=native
spring.cloud.config.server.native.searchLocations=./common-config
config/bootstrap.properties

Discovery

Eureka, the Netflix Service Discovery Server and Client is provided.

Run the service in command line in folder jws/jws-discovery/ :

jws-discovery-service.exe --install

jws-discovery-service.exe --start (on Windows in administrator's terminal)

jws-discovery-service start (on Linux)

or

run-jws-discovery.exe (on Windows)

run-jws-discovery(on Linux)

**Default configuration **

**config/application.properties **
server.port=8761
logging.file.name=../logs/jws-disocvery.log
spring.config.import=configserver:${CONFIG_SERVER_URI:http://localhost:8888}?fail-fast=true&max-attempts=100&max-interval=60000&multiplier=1.2&initial-interval=3000 #Added in version 22.6.0.
config/bootstrap.properties
spring.cloud.config.failFast=true #Removed in version 22.6.0.
spring.cloud.config.uri=${CONFIG_SERVER_URI:http://localhost:8888/} #Removed in version 22.6.0.
spring.cloud.config.retry.initialInterval=3000 #Removed in version 22.6.0.
spring.cloud.config.retry.multiplier=1.2 #Removed in version 22.6.0.
spring.cloud.config.retry.maxInterval=60000 #Removed in version 22.6.0.
spring.cloud.config.retry.maxAttempts=100 #Removed in version 22.6.0.

Gateway

Spring Cloud Gateway is provided.

Run the service in command line in folder jws/jws-gateway/ :

jws-gateway-service.exe --install

jws-gateway-service.exe --start (on Windows in administrator's terminal)

jws-gateway-service start (on Linux)

or

run-jws-gateway.exe (on Windows)

run-jws- gateway(on Linux)

**Default configuration: **

**config/application.properties **
server.port=8080 logging.file.name=../logs/jws-gateway.log eureka.client.enabled=true
spring.config.import=configserver:${CONFIG_SERVER_URI:http://localhost:8888}?fail-fast=true&max-attempts=100&max-interval=60000&multiplier=1.2&initial-interval=3000 #Added in version 22.6.0.
config/bootstrap.properties
spring.cloud.config.failFast=true #Removed in version 22.6.0.
spring.cloud.config.uri=${CONFIG_SERVER_URI:http://localhost:8888/} #Removed in version 22.6.0
spring.cloud.config.retry.initialInterval=3000 #Removed in version 22.6.0.
spring.cloud.config.retry.multiplier=1.2 #Removed in version 22.6.0.
spring.cloud.config.retry.maxInterval=60000 #Removed in version 22.6.0.
spring.cloud.config.retry.maxAttempts=100 #Removed in version 22.6.0.

Allow CORS in Gateway

CORS is not allowed by default but can be enabled in Gateway, if required:

**config/application.properties **
management.endpoints.web.cors.allowed-origins=* #Removed in version 22.6.0
management.endpoints.web.cors.allowed-origin-patterns=* #Added in version 22.6.0
management.endpoints.web.cors.allowed-headers=*
management.endpoints.web.cors.allowed-methods=*
management.endpoints.web.cors.allow-credentials=true

Message limitations in Gateway

Our Gateway is a simple Zuul Proxy (https://github.com/Netflix/zuul), developed by Netflix. By default it has a smart algorithm to retry failed requests on different backend instances. For this it keeps each request in memory until it is answered successfully or it cannot be retried on any other servers. This leads us to a limitation where the sent message is kept in memory so if we want to send lots of data at once (like indexing a large batch of molecules), we have to grant enough memory for Zuul to keep our whole request in memory during the process. You can set Gateway's maximum memory as any Java process in the appropriate .vmoptions file. (If you execute the service with jws-gateway-servcie, then use jws-gateway-service.vmoptions; if you execute the service with run-jws-gateway, then use run-jws-gateway.vmoptions.) The default setting is -Xmx256m, which means maximum 256 MB memory.

To protect Gateway from overloading its memory, we have introduced a filter to reject every message where Content-Length header is greater than ⅓ of the available maximum memory. With default memory settings this will lead you to reject every request with body greater than 85 MB.

You can also specify directly how many bytes do you allow in a request. For this set gateway.max-message-size=<number_of_bytes_to_allow> to the number of bytes you want to allow in a request. (Set this as any other property in Config server.)

If a request is too large, then a HTTP 413 error will be returned by the Gateway server.