Git Product home page Git Product logo

portfolio's People

Contributors

andrewdes avatar brutif avatar cvignola avatar dependabot[bot] avatar greghint avatar jwalcorn avatar karricar avatar kittysmithita avatar leochr avatar maxveit avatar raunak-s avatar rtclauss avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

portfolio's Issues

Free trade count is overwritten every time feedback is submitted.

This feels incorrect, everytime I post feedback, the number of free trades I have resets to the value associated with that feedback.

So if I post angry feedback, and I'm granted 3 free trades, then post happy feedback, I'm reset to a single free trade, (which will probably make me angry, and submit more feedback)..

Free trade count for feedback should probably be cumulative, and capped somehow to prevent abuse.

JWT should be used for all aspects of auth. (removal of static user registry from config)

Currently the server is configured to accept JWTs, but also has a basic user registry with roles assigned and groups.

The roles should be coming from the JWT, to avoid embedding user ids and user roles within this service.

This service should only be validating the JWT, using the user id from within the token, and honoring the roles allowed by the token.

Version tag missing from docker plugin in pom.xml

[WARNING]
[WARNING] Some problems were encountered while building the effective model for com.stocktrader:portfolio:war:1.0-SNAPSHOT
[WARNING] 'build.plugins.plugin.version' for io.fabric8:docker-maven-plugin is missing. @ line 123, column 21
[WARNING]
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING]
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING]

Private keys should not be checked into github, or baked into docker image.

Keys for microservices should be supplied as configuration via k8s secrets, having them present in github kinda defeats the purpose of them being secret.

This is a placeholder issue to track removal of the keys, updating the project to use k8s secret provisioned keys, and adding the documentation to cover the creation of the secrets.

Concurrent Delete

Was seeing the following error in portfolio

WTRN0074E: Exception caught from before_completion synchronization operation: javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.10.v20211216-fe64cd39c3): org.eclipse.persistence.exceptions.DatabaseException\nInternal Exception: org.postgresql.util.PSQLException: ERROR: could not serialize access due to concurrent delete\nError Code: 0\nCall: DELETE FROM STOCK WHERE ((SYMBOL = ?) AND (owner = ?))\n\tbind => [2 parameters bound]\nQuery: DeleteObjectQuery({\"symbol\": \"AMZN\", \"shares\": 5, \"commission\": 9.99, \"price\": 140.8, \"total\": 704.0, \"date\": \"2022-08-05\"})\n\tat org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl$1.handleException(EntityManagerSetupImpl.java:788)\n\tat

Googling led to this answer
https://stackoverflow.com/questions/38466095/in-a-was-liberty-connection-pool-can-i-validate-connections-on-borrow

So the connection pool should be:

<connectionManager id="dbConnections" maxPoolSize="50" purgePolicy="ValidateAllConnections" validationTimeout="10m"/>

I've been running this for 2 months now without seeing any more concurrent delete errors in portfolio.

Update secret value bindings to match Service Broker generated secrets

In an effort to consolidate secrets (IBMStockTrader/trade-history#36), some bindings should be updated to be compatible with Service Broker generated secrets.

The following bindings need to be changed:

  • api-key -> apikey
  • address -> url

Topic and Consumer Group ID are not included in the generated secret from Service Broker, and are currently being stored in a manually created kafka-extra secret.

  • kafka:topic -> kafka-extra:topic

Kafka Authenticaion Mechanism for AWS differs from IBM Cloud

When using IBM EventStreams/Kafka the authentication mechanism is via username/password using the PLAIN SASL Mechanism. This can be partially seen in EventStreamsProducer.java:

...
        properties.put(SaslConfigs.SASL_MECHANISM, "PLAIN");
        properties.put(SaslConfigs.SASL_JAAS_CONFIG, "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"" + USERNAME + "\" password=\"" + API_KEY + "\";");
 ...       

However, Amazon MSK uses a different set of SASL mechanisms as outlined below:

...
        properties.put(SaslConfigs.SASL_MECHANISM, "SCRAM-SHA-512");
        properties.put(SaslConfigs.SASL_JAAS_CONFIG, "org.apache.kafka.common.security.scram.ScramLoginModule required username=\"" + USERNAME + "\" password=\"" + API_KEY + "\";");
...

Azure Event Hubs can make use of the same, PLAIN, configuration or it can use OAUTHBEARER tokens with callback.

We need a generic mechanism to specify the SASL configuration for Kafka.

Connection to MQ failed when MQ required a password for user app

The current stocktrader can connect to MQ which the MQ itself have no password configured for user app.

when trying to connecting to MQ which the MQ itself have a password configured for user app, it will be failed.

so, there might be a hardcoded/constrain "BLANK" password for MQ in app stocktrader

so, we better ether :

  1. ask user not to configure the MQ with password for user app, when installing MQ for stocktrader.
  2. change the code of stocktrader to handle the password input from credential secret, to parse it and use it to connect to the target mq( either with specific value or blank, depending on actual case.

below is the MQ log when stocktrader connecting to a MQ which password setup for app user:
04/10/20 14:38:09 - Process(434.319) User(mqm) Program(amqrmppa)
Host(stocktrader-mq-ibm-mq-0) Installation(Installation1)
VRMF(9.1.5.0) QMgr(stocktradermq)
Time(2020-04-10T14:38:09.426Z)
RemoteHost(172.30.130.217)
CommentInsert1(jar)
CommentInsert2(172.30.130.217)
CommentInsert3(MCAUSER(app) CLNTUSER(default))
AMQ9791E: The client application did not supply a user ID and password.
EXPLANATION:
The client application 'jar' running on host '172.30.130.217' did not supply a
user ID and password. The channel authentication (CHLAUTH) record for the
connection requires a user ID and password, but none was supplied.
The active values of the channel were 'MCAUSER(app) CLNTUSER(default)'. The
MATCH(RUNCHECK) mode of the DISPLAY CHLAUTH MQSC command can be used to
identify the relevant CHLAUTH record.
ACTION:
Ensure that the application provides a valid user ID and password, or change
the queue manager connection authority (CONNAUTH) configuration to OPTIONAL to
allow client applications to connect which have not supplied a user ID and
password.

Event Stream secret to use service name

If Event Stream is deployed on ICP, service name should be used to access service stream. For example:

kubectl create secret generic kafka -n stock-trader --from-literal=topic=stocktrader --from-literal=address=event-streams-trader-ibm-es-proxy-svc.event-streams.svc.cluster.local:30001 --from-literal=user=token --from-literal=api-key=

Portfolio does not call Watson service from IKS

Stock Trader portfolio service works great in ICP.

However, when we port it to IKS, the Watson service does not get called.

[INFO    ] Error from Watson
[WARNING ] javax.ws.rs.WebApplicationException: HTTP 400 Bad Request
[INFO    ] javax.ws.rs.WebApplicationException: HTTP 400 Bad Request```

```{“message”: “Error communicating with the Watson Tone Analyzer”, “free”: 0, “sentiment”: “Unknown”}```

Here's what we know:
- Works fine in ICP
- Tried multiple Tone Analyzer services but no luck
- We confirmed the failure on other IKS instances, so it's not limited to our instance.

default key has expired.

The default key in the supplied key.jks expired at the start of October.

Alias name: default
Creation date: Oct 1, 2017
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=localhost, OU=StockTrader, O=ibm, C=us
Issuer: CN=localhost, OU=StockTrader, O=ibm, C=us
Serial number: 5da80e03
Valid from: Sun Oct 01 17:53:22 EDT 2017 until: Mon Oct 01 17:53:22 EDT 2018

Refactor project to use packages

As a starting suggestion,

  • clients
  • pojos/datamodel/model

And leave the main app where it is.

Any sort of hierarchical grouping will vastly help people understand the codebase

Update can add negative levels of stock. Negative stock handling requires error cases.

If the PUT call is for a stock not currently held by the identified portfolio, and the stock level specified is negative. The insert will succeed and store a negative quantity of stock.

Handling for negative amounts is never really clear, it should probably result in an error, and the request being rejected entirely if a request drives a stock to negative levels, as it would imply the portfolio was not in the state the user expected. (eg, tring to remove 2000 shares from a holding of 20 should result in silently dropping the 20 shares as a 'success' it should be an error that the other 1980 requested removals were not possible, and thus the request was aborted)

Liberty plugin missing from the pom.xml

INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.493s
[INFO] Finished at: Mon Apr 02 22:54:43 EDT 2018
[INFO] Final Memory: 12M/130M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal on project portfolio: Could not resolve dependencies for project com.stocktrader:portfolio:war:1.0-SNAPSHOT: The following artifacts could not be resolved: net.wasdev.wlp.starters.ms-builder:config:jar:0.1, net.wasdev.wlp.starters.ms-builder:faulttolerance:jar:0.1: Failure to find net.wasdev.wlp.starters.ms-builder:config:jar:0.1 in http://liberty-app-accelerator.wasdev.developer.ibm.com/start/api/v1/repo was cached in the local repository, resolution will not be reattempted until the update interval of liberty-starter-maven-repo has elapsed or updates are forced -> [Help 1]

Watson no longer provides userid/password based credentials.

Watson has moved over to iam/apikey based auth.

Newly deployed Watson services do not offer Userid/Password based credentials, only apikey instead.

Current portfolio implementation does not support this, so it is no longer possible to deploy new instances of StockTrader.

Database Concurrent Update Error

Recreating the Error

  1. Make a new portfolio
  2. Buy Stock with the portfolio
  3. Swap the stock and number of stocks to buy
  4. Click submit and get 500 error
  5. Return to previous page
  6. Buy stock correctly

When the steps above are recreated, the error message below generates. I'm currently unsure of what this would affect

Portfolio's log:

Launching defaultServer (Open Liberty 22.0.0.12/wlp-1.0.71.cl221220221107-1900) on Eclipse OpenJ9 VM, version 17.0.5+8 (en_US)
[AUDIT   ] CWWKE0001I: The server defaultServer has been launched.
[AUDIT   ] CWWKG0093A: Processing configuration drop-ins resource: /opt/ol/wlp/usr/servers/defaultServer/configDropins/defaults/keystore.xml
[AUDIT   ] CWWKG0093A: Processing configuration drop-ins resource: /opt/ol/wlp/usr/servers/defaultServer/configDropins/defaults/open-default-port.xml
[AUDIT   ] CWWKG0028A: Processing included configuration resource: /opt/ol/wlp/usr/servers/defaultServer/includes/postgres.xml
[INFO    ] CWWKE0002I: The kernel started after 6.603 seconds
[INFO    ] CWWKF0007I: Feature update started.
[INFO    ] CWWKS0007I: The security service is starting...
[AUDIT   ] CWWKZ0058I: Monitoring dropins for applications.
[INFO    ] DYNA1001I: WebSphere Dynamic Cache instance named baseCache initialized successfully.
[INFO    ] DYNA1071I: The cache provider default is being used.
[INFO    ] DYNA1056I: Dynamic Cache (object cache) initialized successfully.
[INFO    ] CWWKS5780I: The MicroProfile JWT version 1.2 mpConfigProxy processed successfully.
[INFO    ] CWWKS4103I: Creating the LTPA keys. This may take a few seconds.
[INFO    ] CWWKS1123I: The collective authentication plugin with class name NullCollectiveAuthenticationPlugin has been activated. 
[INFO    ] CWPKI0830I: Certificate with the CN=IBM Cloud Databases SubjectDN from the cert_defaultTrustStore environment variable is being added to the defaultTrustStore keystore.
[INFO    ] CWPKI0830I: Certificate with the CN=Amazon RDS Root 2019 CA,OU=Amazon RDS,O=Amazon Web Services\, Inc.,ST=Washington,L=Seattle,C=US SubjectDN from the cert_defaultTrustStore environment variable is being added to the defaultTrustStore keystore.
[INFO    ] CWPKI0830I: Certificate with the CN=Amazon RDS us-east-1 2019 CA,OU=Amazon RDS,O=Amazon Web Services\, Inc.,L=Seattle,ST=Washington,C=US SubjectDN from the cert_defaultTrustStore environment variable is being added to the defaultTrustStore keystore.
[INFO    ] CWPKI0830I: Certificate with the L=Seattle,CN=Amazon RDS us-east-1 Root CA RSA2048 G1,ST=WA,OU=Amazon RDS,O=Amazon Web Services\, Inc.,C=US SubjectDN from the cert_defaultTrustStore environment variable is being added to the defaultTrustStore keystore.
[INFO    ] CWPKI0830I: Certificate with the L=Seattle,CN=Amazon RDS us-east-1 Root CA RSA4096 G1,ST=WA,OU=Amazon RDS,O=Amazon Web Services\, Inc.,C=US SubjectDN from the cert_defaultTrustStore environment variable is being added to the defaultTrustStore keystore.
[INFO    ] CWPKI0830I: Certificate with the L=Seattle,CN=Amazon RDS us-east-1 Root CA ECC384 G1,ST=WA,OU=Amazon RDS,O=Amazon Web Services\, Inc.,C=US SubjectDN from the cert_defaultTrustStore environment variable is being added to the defaultTrustStore keystore.
[INFO    ] CWWKS1655I: The default Java Authentication SPI for Containers (JASPIC) AuthConfigFactory class com.ibm.ws.security.jaspi.ProviderRegistry is being used because the Java security property authconfigprovider.factory is not set. 
[INFO    ] Successfully loaded default keystore: /opt/ol/wlp/usr/servers/defaultServer/resources/security/key.p12 of type: pkcs12
[AUDIT   ] CWWKS4104A: LTPA keys created in 3.198 seconds. LTPA key file: /opt/ol/wlp/output/defaultServer/resources/security/ltpa.keys
[INFO    ] CWWKS4105I: LTPA configuration is ready after 3.324 seconds.
[INFO    ] CWWKS6012I: The JSON Web Token (JWT) consumer service is available.
[INFO    ] CWWKS6002I: The JSON Web Token (JWT) endpoint service is available.
[INFO    ] CWWKS5500I: The MicroProfile JWT configuration [MicroProfileJwtService] was successfully processed.
[INFO    ] CWWKS5500I: The MicroProfile JWT configuration [defaultMpJwt] was successfully processed.
[INFO    ] CWWKS5500I: The MicroProfile JWT configuration [stockTraderJWT] was successfully processed.
[INFO    ] SESN8501I: The session manager did not find a persistent storage location; HttpSession objects will be stored in the local application server's memory.
[INFO    ] CWPMI2003I: Monitoring metrics can be retrieved through mpMetrics.
[INFO    ] SRVE0169I: Loading Web Module: health.
[INFO    ] SRVE0250I: Web Module health has been bound to default_host.
[AUDIT   ] CWWKT0016I: Web application available (default_host): http://cjot-portfolio-864555bc-7hdzq:9080/health/
[INFO    ] SRVE0169I: Loading Web Module: ibm/api.
[INFO    ] SRVE0250I: Web Module ibm/api has been bound to default_host.
[AUDIT   ] CWWKT0016I: Web application available (default_host): http://cjot-portfolio-864555bc-7hdzq:9080/ibm/api/
[INFO    ] SRVE0169I: Loading Web Module: IBMJMXConnectorREST.
[INFO    ] SRVE0250I: Web Module IBMJMXConnectorREST has been bound to default_host.
[AUDIT   ] CWWKT0016I: Web application available (default_host): http://cjot-portfolio-864555bc-7hdzq:9080/IBMJMXConnectorREST/
[INFO    ] CWWKX0103I: The JMX REST connector is running and is available at the following service URL: service:jmx:rest://cjot-portfolio-864555bc-7hdzq:9443/IBMJMXConnectorREST
[INFO    ] CWWKX0103I: The JMX REST connector is running and is available at the following service URL: service:jmx:rest://cjot-portfolio-864555bc-7hdzq:9443/IBMJMXConnectorREST
[INFO    ] SRVE0169I: Loading Web Module: PublicMicroProfileMetrics.
[INFO    ] SRVE0250I: Web Module PublicMicroProfileMetrics has been bound to default_host.
[AUDIT   ] CWWKT0016I: Web application available (default_host): http://cjot-portfolio-864555bc-7hdzq:9080/metrics/
[INFO    ] SRVE0169I: Loading Web Module: OpenAPIUI.
[INFO    ] SRVE0250I: Web Module OpenAPIUI has been bound to default_host.
[AUDIT   ] CWWKT0016I: Web application available (default_host): http://cjot-portfolio-864555bc-7hdzq:9080/openapi/ui/
[INFO    ] SRVE0169I: Loading Web Module: com.ibm.ws.security.jwt.
[INFO    ] SRVE0250I: Web Module com.ibm.ws.security.jwt has been bound to default_host.
[AUDIT   ] CWWKT0016I: Web application available (default_host): http://cjot-portfolio-864555bc-7hdzq:9080/jwt/
[INFO    ] CWWKZ0018I: Starting application Portfolio.
[INFO    ] CWWKZ0136I: The Portfolio application is using the archive file at the /opt/ol/wlp/usr/servers/defaultServer/apps/Portfolio.war location.
[INFO    ] SRVE0169I: Loading Web Module: /openapi/platform.
[INFO    ] SRVE0250I: Web Module /openapi/platform has been bound to default_host.
[AUDIT   ] CWWKT0016I: Web application available (default_host): http://cjot-portfolio-864555bc-7hdzq:9080/openapi/platform/
[INFO    ] SRVE0169I: Loading Web Module: MicroProfileOpenAPI.
[INFO    ] SRVE0250I: Web Module MicroProfileOpenAPI has been bound to default_host.
[AUDIT   ] CWWKT0016I: Web application available (default_host): http://cjot-portfolio-864555bc-7hdzq:9080/openapi/
[INFO    ] SESN0176I: A new session context will be created for application key default_host/ibm/api
[INFO    ] SESN0176I: A new session context will be created for application key default_host/health
[INFO    ] SESN0172I: The session manager is using the Java default SecureRandom implementation for session ID generation.
[INFO    ] SESN0172I: The session manager is using the Java default SecureRandom implementation for session ID generation.
[INFO    ] DYNA1056I: Dynamic Cache (object cache) initialized successfully.
[INFO    ] SRVE0242I: [io.openliberty.microprofile.health.3.1.internal] [/health] [HealthCheckReadinessServlet]: Initialization successful.
[INFO    ] SRVE0242I: [io.openliberty.microprofile.health.3.1.internal] [/health] [HealthCheckServlet]: Initialization successful.
[INFO    ] SRVE0242I: [io.openliberty.microprofile.health.3.1.internal] [/health] [HealthCheckStartupServlet]: Initialization successful.
[INFO    ] SRVE0242I: [io.openliberty.microprofile.health.3.1.internal] [/health] [HealthCheckLivenessServlet]: Initialization successful.
[INFO    ] SESN0176I: A new session context will be created for application key default_host/IBMJMXConnectorREST
[INFO    ] SESN0172I: The session manager is using the Java default SecureRandom implementation for session ID generation.
[INFO    ] SRVE0242I: [com.ibm.ws.jmx.connector.server.rest] [/IBMJMXConnectorREST] [JMXRESTProxyServlet]: Initialization successful.
[INFO    ] SESN0176I: A new session context will be created for application key default_host/metrics
[INFO    ] SESN0172I: The session manager is using the Java default SecureRandom implementation for session ID generation.
[INFO    ] SRVE0242I: [io.openliberty.microprofile.metrics.internal.public] [/metrics] [PublicMetricsRESTProxyServlet]: Initialization successful.
[INFO    ] SRVE9103I: A configuration file for a web server plugin was automatically generated for this server at /opt/ol/wlp/output/defaultServer/logs/state/plugin-cfg.xml.
[INFO    ] SESN0176I: A new session context will be created for application key default_host/openapi/ui
[INFO    ] SESN0172I: The session manager is using the Java default SecureRandom implementation for session ID generation.
[INFO    ] SESN0176I: A new session context will be created for application key default_host/openapi/platform
[INFO    ] SESN0172I: The session manager is using the Java default SecureRandom implementation for session ID generation.
[INFO    ] SESN0176I: A new session context will be created for application key default_host/jwt
[INFO    ] SESN0172I: The session manager is using the Java default SecureRandom implementation for session ID generation.
[INFO    ] SESN0176I: A new session context will be created for application key default_host/openapi
[INFO    ] SESN0172I: The session manager is using the Java default SecureRandom implementation for session ID generation.
[INFO    ] SRVE0242I: [io.openliberty.microprofile.openapi.2.0.internal] [/openapi] [ApplicationServlet]: Initialization successful.
[INFO    ] J2CA8050I: An authentication alias should be used instead of defining a user name and password on dataSource[PortfolioDB].
[INFO    ] CWRLS0010I: Performing recovery processing for local WebSphere server (defaultServer).
[INFO    ] CWRLS0007I: No existing recovery log files found in /opt/ol/wlp/output/defaultServer/tranlog/tranlog. Cold starting the recovery log.
[INFO    ] CWRLS0006I: Creating new recovery log file /opt/ol/wlp/output/defaultServer/tranlog/tranlog/log1.
[INFO    ] CWRLS0006I: Creating new recovery log file /opt/ol/wlp/output/defaultServer/tranlog/tranlog/log2.
[INFO    ] CWRLS0007I: No existing recovery log files found in /opt/ol/wlp/output/defaultServer/tranlog/partnerlog. Cold starting the recovery log.
[INFO    ] CWRLS0006I: Creating new recovery log file /opt/ol/wlp/output/defaultServer/tranlog/partnerlog/log1.
[INFO    ] CWRLS0006I: Creating new recovery log file /opt/ol/wlp/output/defaultServer/tranlog/partnerlog/log2.
[INFO    ] CWRLS0012I: All persistent services have been directed to perform recovery processing for this WebSphere server (defaultServer).
[INFO    ] WTRN0135I: Transaction service recovering no transactions.
[WARNING ] You have specified multiple ids for the entity class [com.ibm.hybrid.cloud.sample.stocktrader.portfolio.json.Stock] without specifying an @IdClass. By doing this you may lose the ability to find by identity, distributed cache support etc. Note: You may however use EntityManager find operations by passing a list of primary key fields. Else, you will have to use JPQL queries to read your entities. For other id options see @PrimaryKey.
[INFO    ] CWWKO1660I: The application Portfolio was processed and an OpenAPI document was produced.
[INFO    ] WELD-000900: 3.1.9 (Final)
[INFO    ] CWWKO0219I: TCP Channel defaultHttpEndpoint has been started and is now listening for requests on host *  (IPv6) port 9080.
[INFO    ] CWWKO0219I: TCP Channel defaultHttpEndpoint-ssl has been started and is now listening for requests on host *  (IPv6) port 9443.
[AUDIT   ] CWWKF0012I: The server installed the following features: [json-1.0, jwt-1.0, microProfile-4.1, monitor-1.0, mpConfig-2.0, mpFaultTolerance-3.0, mpHealth-3.1, mpJwt-1.2, mpMetrics-3.0, mpOpenAPI-2.0, mpOpenTracing-2.0, mpRestClient-2.0, opentracing-2.0, restConnector-2.0].
[AUDIT   ] CWWKF0013I: The server removed the following features: [appClientSupport-1.0, batch-1.0, beanValidation-2.0, concurrent-1.0, ejb-3.2, ejbHome-3.2, ejbLite-3.2, ejbPersistentTimer-3.2, ejbRemote-3.2, j2eeManagement-1.1, jacc-1.5, jaspic-1.1, javaMail-1.6, javaee-8.0, jaxb-2.2, jaxws-2.2, jca-1.7, jcaInboundSecurity-1.0, jms-2.0, jsf-2.3, jsp-2.3, managedBeans-1.0, mdb-3.2, wasJmsClient-2.0, wasJmsSecurity-1.0, wasJmsServer-1.0, webProfile-8.0, websocket-1.1].
[INFO    ] CWWKF0008I: Feature update completed in 49.792 seconds.
[AUDIT   ] CWWKF0011I: The defaultServer server is ready to run a smarter planet. The defaultServer server started in 56.313 seconds.
[AUDIT   ] CWWKZ0022W: Application Portfolio has not started in 30.318 seconds.
[INFO    ] Publishing to Trade History topic enabled: false
[INFO    ] Cash Account microservice enabled: false
[INFO    ] Using Stock Quote URL from config map: http://cjot-stock-quote-service:9080/stock-quote
[INFO    ] CWWKW0750I: The following interfaces are configured as RequestScoped which will result in slower performance:  Consider using ApplicationScoped for better performance.
[INFO    ] SRVE0169I: Loading Web Module: Portfolio.
[INFO    ] SRVE0250I: Web Module Portfolio has been bound to default_host.
[AUDIT   ] CWWKT0016I: Web application available (default_host): http://cjot-portfolio-864555bc-7hdzq:9080/portfolio/
[INFO    ] SESN0176I: A new session context will be created for application key default_host/portfolio
[INFO    ] SESN0172I: The session manager is using the Java default SecureRandom implementation for session ID generation.
[AUDIT   ] CWWKZ0001I: Application Portfolio started in 31.589 seconds.
[INFO    ] CWWKS9123I:  For URL /* in application Portfolio, the following HTTP methods are uncovered, and not accessible: HEAD OPTIONS TRACE 
[INFO    ] SRVE9103I: A configuration file for a web server plugin was automatically generated for this server at /opt/ol/wlp/output/defaultServer/logs/state/plugin-cfg.xml.
[INFO    ] Setting the server's publish address to be /
[INFO    ] SRVE0242I: [Portfolio] [/portfolio] [com.ibm.hybrid.cloud.sample.stocktrader.portfolio.PortfolioService]: Initialization successful.
[err] SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
[err] SLF4J: Defaulting to no-operation (NOP) logger implementation
[err] SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
[INFO    ] CWMOT1001I: A JaegerTracer instance was created for the Portfolio application.  Tracing information is sent to localhost:6831.
[INFO    ] EclipseLink, version: Eclipse Persistence Services - 2.7.11.v20220804-52dea2a3c0
[INFO    ] DSRA8203I: Database product name : PostgreSQL
[INFO    ] DSRA8204I: Database product version : 12.12
[INFO    ] DSRA8205I: JDBC driver name  : PostgreSQL JDBC Driver
[INFO    ] DSRA8206I: JDBC driver version  : 42.5.3
[WARNING ] 

Internal Exception: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "stock_pkey"
  Detail: Key (owner, symbol)=(Testing, KD) already exists.
Error Code: 0
Call: INSERT INTO STOCK (SYMBOL, COMMISSION, dateQuoted, PRICE, SHARES, TOTAL, owner) VALUES (?, ?, ?, ?, ?, ?, ?)
	bind => [7 parameters bound]
Query: InsertObjectQuery({"symbol": "KD", "shares": 10, "commission": 0.0, "price": 0.0, "total": 0.0, "date": "null"})
[WARNING ] Failure refreshing portfolio for Testing
[WARNING ] javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.11.v20220804-52dea2a3c0): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "stock_pkey"
  Detail: Key (owner, symbol)=(Testing, KD) already exists.
Error Code: 0
Call: INSERT INTO STOCK (SYMBOL, COMMISSION, dateQuoted, PRICE, SHARES, TOTAL, owner) VALUES (?, ?, ?, ?, ?, ?, ?)
	bind => [7 parameters bound]
Query: InsertObjectQuery({"symbol": "KD", "shares": 10, "commission": 0.0, "price": 0.0, "total": 0.0, "date": "null"})
[INFO    ] javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.11.v20220804-52dea2a3c0): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "stock_pkey"
  Detail: Key (owner, symbol)=(Testing, KD) already exists.
Error Code: 0
Call: INSERT INTO STOCK (SYMBOL, COMMISSION, dateQuoted, PRICE, SHARES, TOTAL, owner) VALUES (?, ?, ?, ?, ?, ?, ?)
	bind => [7 parameters bound]
Query: InsertObjectQuery({"symbol": "KD", "shares": 10, "commission": 0.0, "price": 0.0, "total": 0.0, "date": "null"})
	at org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:980)
	at org.eclipse.persistence.internal.jpa.QueryImpl.performPreQueryFlush(QueryImpl.java:978)
	at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:211)
	at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:482)
	at com.ibm.hybrid.cloud.sample.stocktrader.portfolio.dao.StockDao.readStockByOwner(StockDao.java:56)
	at com.ibm.hybrid.cloud.sample.stocktrader.portfolio.dao.StockDao$Proxy$_$$_WeldClientProxy.readStockByOwner(Unknown Source)
	at com.ibm.hybrid.cloud.sample.stocktrader.portfolio.PortfolioService.getPortfolio(PortfolioService.java:255)
	at com.ibm.hybrid.cloud.sample.stocktrader.portfolio.PortfolioService$Proxy$_$$_WeldSubclass.getPortfolio(Unknown Source)
	at com.ibm.hybrid.cloud.sample.stocktrader.portfolio.PortfolioService.updatePortfolio(PortfolioService.java:420)
	at com.ibm.hybrid.cloud.sample.stocktrader.portfolio.PortfolioService$Proxy$_$$_WeldSubclass.updatePortfolio$$super(Unknown Source)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.jboss.weld.interceptor.proxy.TerminalAroundInvokeInvocationContext.proceedInternal(TerminalAroundInvokeInvocationContext.java:51)
	at org.jboss.weld.interceptor.proxy.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:78)
	at com.ibm.tx.jta.cdi.interceptors.TransactionalInterceptor$1.run(TransactionalInterceptor.java:137)
	at com.ibm.ws.uow.embeddable.EmbeddableUOWManagerImpl.runUnderCurrentUOW(EmbeddableUOWManagerImpl.java:1077)
	at com.ibm.ws.uow.embeddable.EmbeddableUOWManagerImpl.runUnderNewUOW(EmbeddableUOWManagerImpl.java:1040)
	at com.ibm.ws.uow.embeddable.EmbeddableUOWManagerImpl.runUnderUOW(EmbeddableUOWManagerImpl.java:1013)
	at com.ibm.tx.jta.cdi.interceptors.TransactionalInterceptor.runUnderUOWManagingEnablement(TransactionalInterceptor.java:151)
	at com.ibm.tx.jta.cdi.interceptors.Required.required(Required.java:40)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.jboss.weld.interceptor.reader.SimpleInterceptorInvocation$SimpleMethodInvocation.invoke(SimpleInterceptorInvocation.java:73)
	at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.executeAroundInvoke(InterceptorMethodHandler.java:84)
	at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.executeInterception(InterceptorMethodHandler.java:72)
	at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.invoke(InterceptorMethodHandler.java:56)
	at org.jboss.weld.bean.proxy.CombinedInterceptorAndDecoratorStackMethodHandler.invoke(CombinedInterceptorAndDecoratorStackMethodHandler.java:79)
	at org.jboss.weld.bean.proxy.CombinedInterceptorAndDecoratorStackMethodHandler.invoke(CombinedInterceptorAndDecoratorStackMethodHandler.java:68)
	at com.ibm.hybrid.cloud.sample.stocktrader.portfolio.PortfolioService$Proxy$_$$_WeldSubclass.updatePortfolio(Unknown Source)
	at com.ibm.hybrid.cloud.sample.stocktrader.portfolio.PortfolioService$Proxy$_$$_WeldClientProxy.updatePortfolio(Unknown Source)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at com.ibm.ws.jaxrs20.cdi.component.JaxRsFactoryImplicitBeanCDICustomizer.serviceInvoke(JaxRsFactoryImplicitBeanCDICustomizer.java:350)
	at com.ibm.ws.jaxrs20.server.LibertyJaxRsServerFactoryBean.performInvocation(LibertyJaxRsServerFactoryBean.java:641)
	at com.ibm.ws.jaxrs20.server.LibertyJaxRsInvoker.performInvocation(LibertyJaxRsInvoker.java:160)
	at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:101)
	at com.ibm.ws.jaxrs20.server.LibertyJaxRsInvoker.invoke(LibertyJaxRsInvoker.java:273)
	at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:213)
	at com.ibm.ws.jaxrs20.server.LibertyJaxRsInvoker.invoke(LibertyJaxRsInvoker.java:444)
	at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:112)
	at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)
	at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96)
	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
	at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:123)
	at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:277)
	at com.ibm.ws.jaxrs20.endpoint.AbstractJaxRsWebEndpoint.invoke(AbstractJaxRsWebEndpoint.java:137)
	at com.ibm.websphere.jaxrs.server.IBMRestServlet.handleRequest(IBMRestServlet.java:146)
	at com.ibm.websphere.jaxrs.server.IBMRestServlet.doPut(IBMRestServlet.java:136)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
	at com.ibm.websphere.jaxrs.server.IBMRestServlet.service(IBMRestServlet.java:96)
	at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1258)
	at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:746)
	at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:443)
	at com.ibm.ws.webcontainer.filter.WebAppFilterChain.invokeTarget(WebAppFilterChain.java:193)
	at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:98)
	at com.ibm.ws.security.jaspi.JaspiServletFilter.doFilter(JaspiServletFilter.java:56)
	at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:201)
	at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:91)
	at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:1002)
	at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1140)
	at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1011)
	at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:75)
	at com.ibm.ws.webcontainer40.servlet.CacheServletWrapper40.handleRequest(CacheServletWrapper40.java:85)
	at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:938)
	at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost$2.run(DynamicVirtualHost.java:281)
	at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink$TaskWrapper.run(HttpDispatcherLink.java:1246)
	at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink.wrapHandlerAndExecute(HttpDispatcherLink.java:468)
	at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink.ready(HttpDispatcherLink.java:427)
	at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:567)
	at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.handleNewRequest(HttpInboundLink.java:501)
	at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.processRequest(HttpInboundLink.java:361)
	at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.ready(HttpInboundLink.java:328)
	at com.ibm.ws.tcpchannel.internal.NewConnectionInitialReadCallback.sendToDiscriminators(NewConnectionInitialReadCallback.java:167)
	at com.ibm.ws.tcpchannel.internal.NewConnectionInitialReadCallback.complete(NewConnectionInitialReadCallback.java:75)
	at com.ibm.ws.tcpchannel.internal.WorkQueueManager.requestComplete(WorkQueueManager.java:514)
	at com.ibm.ws.tcpchannel.internal.WorkQueueManager.attemptIO(WorkQueueManager.java:584)
	at com.ibm.ws.tcpchannel.internal.WorkQueueManager.workerRun(WorkQueueManager.java:968)
	at com.ibm.ws.tcpchannel.internal.WorkQueueManager$Worker.run(WorkQueueManager.java:1057)
	at com.ibm.ws.threading.internal.ExecutorServiceImpl$RunnableWrapper.run(ExecutorServiceImpl.java:245)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:857)
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.11.v20220804-52dea2a3c0): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "stock_pkey"
  Detail: Key (owner, symbol)=(Testing, KD) already exists.
Error Code: 0
Call: INSERT INTO STOCK (SYMBOL, COMMISSION, dateQuoted, PRICE, SHARES, TOTAL, owner) VALUES (?, ?, ?, ?, ?, ?, ?)
	bind => [7 parameters bound]
Query: InsertObjectQuery({"symbol": "KD", "shares": 10, "commission": 0.0, "price": 0.0, "total": 0.0, "date": "null"})
	at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:342)
	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.processExceptionForCommError(DatabaseAccessor.java:1666)
	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:915)
	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:979)
	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:640)
	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:567)
	at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:2105)
	at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:313)
	at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:275)
	at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:261)
	at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.insertObject(DatasourceCallQueryMechanism.java:428)
	at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:168)
	at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:183)
	at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:515)
	at org.eclipse.persistence.queries.InsertObjectQuery.executeCommit(InsertObjectQuery.java:85)
	at org.eclipse.persistence.queries.InsertObjectQuery.executeCommitWithChangeSet(InsertObjectQuery.java:95)
	at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:327)
	at org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:60)
	at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:913)
	at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:812)
	at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:110)
	at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:87)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:3004)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1898)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1880)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1830)
	at org.eclipse.persistence.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet(CommitManager.java:229)
	at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:128)
	at org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:4409)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1503)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithPreBuiltChangeSet(UnitOfWorkImpl.java:1649)
	at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.writeChanges(RepeatableWriteUnitOfWork.java:457)
	at org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:975)
	... 87 more
Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "stock_pkey"
  Detail: Key (owner, symbol)=(Testing, KD) already exists.
	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2676)
	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2366)
	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:356)
	at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:496)
	at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:413)
	at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:190)
	at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:152)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.postgresql.ds.PGPooledConnection$StatementHandler.invoke(PGPooledConnection.java:441)
	at jdk.proxy31/jdk.proxy31.$Proxy128.executeUpdate(Unknown Source)
	at com.ibm.ws.rsadapter.jdbc.WSJdbcPreparedStatement.executeUpdate(WSJdbcPreparedStatement.java:520)
	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:907)
	... 117 more

KeyStore is really a TrustStore?

There should be a separation of keystore and truststore

Keystore is for private keys, used for signing stuff, or hosting https endpoints.

Truststore is for verifying stuff, jwts, or connecting to https endpoints.

Truststore should never contain private keys.

Portfolio probably only needs to be using a Truststore to validate JWTs with a public key. (And to trust the outbound calls for watson etc).

Consider requiring Kafka connection to start

In trying to utilize using Kafka with IBM Event Stream, I think it is best to ensure that Kafka is able to connect properly with an event stream to avoid data going out of sync (between portfolio and the event stream).

This may add some overhead work to make sure secrets are setup properly.

The same should be done on any consumers to ensure that they only consume when they are able to correctly process/store the consumed events.

Usually the logs look like this:

log:[WARNING ] Failure sending message to Kafka
log:[WARNING ] java.util.concurrent.ExecutionException: org.apache.kafka.common.errors.SslAuthenticationException: SSL handshake failed
log: Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem

Update Kafka topic usage for trade history

The current implementation of portfolio uses a config map entry from kafka.historyTopic which is mapped to the environment variable KAFKA_HISTORY_TOPIC to determine which Kafka topic to forward trade history to. In the current implementation the topic is decided by KAFKA_TOPIC which is not currently used which means we use the default topic, stocktrader.

Let's update portfolio to use KAFKA_HISTORY_TOPIC.

Switch from raw JDBC to JPA

Idea is to define a POJO with an @Entity annotation with a getter/setter for each column, per table (Portfolio and Stock). Then PortfolioService.java would just call those accessor methods on the appropriate POJO to persist/retrieve data to/from the JDBC database (such as DB2).

Right now I'm doing things the way you would have 20 years ago - time to move up to something more modern (and to make the code a bit more similar to the Spring version).

There's a pretty good example here: http://www.vogella.com/tutorials/JavaPersistenceAPI/article.html

Postgres SSL configuration false flag appears not to work

When setting the database to be Postgres and SSL flag to false, it appears to still try the SSL handshake.

See below for a reference code snippet and error output from portfolio logs:

database:
kind: postgres
db: postgres
host: x.x.x.x
id: postgres
password: !@#$%^
port: 5432
ssl: false

SSL HANDSHAKE FAILURE: A signer with SubjectDN [C=US, O="Google, Inc", CN=xyz] was sent from the host [35.239.229.155:5432]. The signer might need to be added to local trust store [/opt/ol/wlp/usr/servers/defaultServer/resources/security/trust.p12], located in SSL configuration alias [defaultSSLConfig]. The extended error message from the SSL handshake exception is: [PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target].

CWPKI0828E: The trustDefaultCerts attribute is enabled but trust was not established by using the default truststore. The extended error message from the SSL handshake exception is: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.
[11/15/21, 19:55:57:348 UTC] 00000025 aultServer/apps/Portfolio.war!/WEB-INF/classes/_jpa-unit.ejb E
Local Exception Stack:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.9.v20210604-2c549e2208): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: SSL error: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target DSRA0010E: SQL State = 08006, Error Code = 0

Change from homegrown to mpRestClient for Stock-Quote has altered behavior.

Originally ALL headers were cloned from the source request to the outbound request to StockQuote, (via copyFromRequest now only the JWT header is being passed on (as an arg to mpRestClient).

Please confirm/document the expected behavior, so other implementations know what is expected.

Cloning all headers might seem excessive, but it would allow for trace span headers to propagate, so wouldn't be entirely unexpected for this kind of onward propagation.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.