This use case demonstrates dynamically adding a data source to your running domain by updating your model and rolling your domain. It demonstrates several features of WDT and Model in Image:
For a detailed description of model updates, see Runtime Updates.
The operator does not support all possible dynamic model updates. For model update limitations, consult Runtime Updates in the Model in Image user docs, and carefully test any model update before attempting a dynamic update in production.
Here are the steps:
Ensure that you have a running domain.
Make sure you have deployed the domain from the Initial use case.
Create a data source model YAML file.
Create a WDT model snippet for a data source (or use the example provided). Make sure that its target is set to cluster-1
, and that its initial capacity is set to 0
.
The reason for the latter is to prevent the data source from causing a WebLogic Server startup failure if it can’t find the database, which would be likely to happen because you haven’t deployed one (unless you’re using the JRF
path through the sample).
Here’s an example data source model configuration that meets these criteria:
resources:
JDBCSystemResource:
mynewdatasource:
Target: 'cluster-1'
JdbcResource:
JDBCDataSourceParams:
JNDIName: [
jdbc/mydatasource1,
jdbc/mydatasource2
]
GlobalTransactionsProtocol: TwoPhaseCommit
JDBCDriverParams:
DriverName: oracle.jdbc.xa.client.OracleXADataSource
URL: '@@SECRET:@@ENV:DOMAIN_UID@@-datasource-secret:url@@'
PasswordEncrypted: '@@SECRET:@@ENV:DOMAIN_UID@@-datasource-secret:password@@'
Properties:
user:
Value: '@@SECRET:@@ENV:DOMAIN_UID@@-datasource-secret:user@@'
oracle.net.CONNECT_TIMEOUT:
Value: 5000
oracle.jdbc.ReadTimeout:
Value: 30000
JDBCConnectionPoolParams:
InitialCapacity: 0
MaxCapacity: '@@SECRET:@@ENV:DOMAIN_UID@@-datasource-secret:max-capacity@@'
TestTableName: SQL ISVALID
TestConnectionsOnReserve: true
Place the previous model snippet in a file named /tmp/mii-sample/mydatasource.yaml
and then use it in the later step where you deploy the model ConfigMap, or alternatively, use the same data source that’s provided in /tmp/mii-sample/model-configmaps/datasource/model.20.datasource.yaml
.
Create the data source secret.
The data source references a new secret that needs to be created. Run the following commands to create the secret:
$ kubectl -n sample-domain1-ns create secret generic \
sample-domain1-datasource-secret \
--from-literal='user=sys as sysdba' \
--from-literal='password=incorrect_password' \
--from-literal='max-capacity=1' \
--from-literal='url=jdbc:oracle:thin:@oracle-db.default.svc.cluster.local:1521/devpdb.k8s'
$ kubectl -n sample-domain1-ns label secret \
sample-domain1-datasource-secret \
weblogic.domainUID=sample-domain1
We deliberately specify an incorrect password and a low maximum pool capacity because we will demonstrate dynamically correcting the data source attributes in the Update 4 use case without requiring rolling the domain.
You name and label secrets using their associated domain UID for two reasons:
weblogic.domainUID
label as a convenience for finding all the resources associated with a domain.Create a ConfigMap with the WDT model that contains the data source definition.
Run the following commands:
$ kubectl -n sample-domain1-ns create configmap sample-domain1-wdt-config-map \
--from-file=/tmp/mii-sample/model-configmaps/datasource
$ kubectl -n sample-domain1-ns label configmap sample-domain1-wdt-config-map \
weblogic.domainUID=sample-domain1
--from-file=
parameter (we suggested /tmp/mii-sample/mydatasource.yaml
earlier).-from-file=
parameter can reference a single file, in which case it puts the designated file in the ConfigMap, or it can reference a directory, in which case it populates the ConfigMap with all of the files in the designated directory.You name and label the ConfigMap using its associated domain UID for two reasons:
weblogic.domainUID
label as a convenience for finding all resources associated with a domain.Update your Domain YAML file to refer to the ConfigMap and Secret.
Option 1: Update a copy of your Domain YAML file from the Initial use case.
In the Initial use case, we suggested creating a Domain YAML file named /tmp/mii-sample/mii-initial.yaml
or using the /tmp/mii-sample/domain-resources/WLS-AI/mii-initial-d1-WLS-AI-v1.yaml
file that is supplied with the sample.
We suggest copying the original Domain YAML file and naming the copy /tmp/mii-sample/mii-update1.yaml
before making any changes.
Working on a copy is not strictly necessary, but it helps keep track of your work for the different use cases in this sample and provides you a backup of your previous work.
Add the secret to its spec.configuration.secrets
stanza:
spec:
...
configuration:
...
secrets:
- sample-domain1-datasource-secret
(Leave any existing secrets in place.)
Change its spec.configuration.model.configMap
to look like the following:
spec:
...
configuration:
...
model:
...
configMap: sample-domain1-wdt-config-map
Apply your changed Domain YAML file:
NOTE: Before you deploy the domain custom resource, determine if you have Kubernetes cluster worker nodes that are remote to your local machine. If so, then you need to put the Domain YAML file’s image in a location that these nodes can access and you may also need to modify your Domain YAML file to reference the new location. See Ensuring your Kubernetes cluster can access images.
$ kubectl apply -f /tmp/mii-sample/mii-update1.yaml
Option 2: Use the updated Domain YAML file that is supplied with the sample:
NOTE: Before you deploy the domain custom resource, determine if you have Kubernetes cluster worker nodes that are remote to your local machine. If so, then you need to put the Domain YAML file’s image in a location that these nodes can access and you may also need to modify your Domain YAML file to reference the new location. See Ensuring your Kubernetes cluster can access images.
$ kubectl apply -f /tmp/mii-sample/domain-resources/WLS-AI/mii-update1-d1-WLS-AI-v1-ds.yaml
Restart (‘roll’) the domain.
Now that the data source is deployed in a ConfigMap and its secret is also deployed, and you have applied an updated Domain YAML file with its spec.configuration.model.configMap
and spec.configuration.secrets
referencing the ConfigMap and secret, tell the operator to roll the domain.
When a model domain restarts, it will rerun its introspector job to regenerate its configuration, and it will also pass the configuration changes found by the introspector to each restarted server.
One way to cause a running domain to restart is to change the domain’s spec.restartVersion
. To do this:
Option 1: Edit your domain custom resource.
kubectl -n sample-domain1-ns edit domain sample-domain1
.spec.restartVersion
field and save.
Option 2: Dynamically change your domain using kubectl patch
.
To get the current restartVersion
call:
$ kubectl -n sample-domain1-ns get domain sample-domain1 '-o=jsonpath={.spec.restartVersion}'
Choose a new restart version that’s different from the current restart version.
Use kubectl patch
to set the new value. For example, assuming the new restart version is 2
:
$ kubectl -n sample-domain1-ns patch domain sample-domain1 --type=json '-p=[{"op": "replace", "path": "/spec/restartVersion", "value": "2" }]'
Option 3: Use the sample helper script.
/tmp/mii-sample/utils/patch-restart-version.sh -n sample-domain1-ns -d sample-domain1
.kubectl get
and kubectl patch
commands as Option 2.Wait for the roll to complete.
Now that you’ve started a domain roll, you’ll need to wait for it to complete if you want to verify that the data source was deployed.
One way to do this is to call kubectl get pods -n sample-domain1-ns --watch
and wait for the pods to cycle back to their ready
state.
For a more detailed view of this activity,
you can use the waitForDomain.sh
sample lifecycle script.
This script provides useful information about a domain’s pods and
optionally waits for its Completed
status condition to become True
.
A Completed
domain indicates that all of its expected
pods have reached a ready
state
plus their target restartVersion
, introspectVersion
, and image
.
For example:
$ cd /tmp/weblogic-kubernetes-operator/kubernetes/samples/scripts/domain-lifecycle
$ ./waitForDomain.sh -n sample-domain1-ns -d sample-domain1 -p Completed
After your domain is running, you can call the sample web application to determine if the data source was deployed.
Send a web application request to the ingress controller:
$ curl -s -S -m 10 -H 'host: sample-domain1-cluster-cluster-1.mii-sample.org' \
http://localhost:30305/myapp_war/index.jsp
Or, if Traefik is unavailable and your Administration Server pod is running, you can run kubectl exec
:
$ kubectl exec -n sample-domain1-ns sample-domain1-admin-server -- bash -c \
"curl -s -S -m 10 http://sample-domain1-cluster-cluster-1:8001/myapp_war/index.jsp"
You will see something like the following:
<html><body><pre>
*****************************************************************
Hello World! This is version 'v1' of the mii-sample JSP web-app.
Welcome to WebLogic Server 'managed-server1'!
domain UID = 'sample-domain1'
domain name = 'domain1'
Found 1 local cluster runtime:
Cluster 'cluster-1'
Found min threads constraint runtime named 'SampleMinThreads' with configured count: 1
Found max threads constraint runtime named 'SampleMaxThreads' with configured count: 10
Found 1 local data source:
Datasource 'mynewdatasource': State='Running', testPool='Failed'
---TestPool Failure Reason---
NOTE: Ignore 'mynewdatasource' failures until the sample's Update 4 use case.
---
...
... invalid host/username/password
...
-----------------------------
*****************************************************************
</pre></body></html>
A TestPool Failure
is expected because we will demonstrate dynamically correcting the data source attributes in Update 4.
If you see an error other than the expected TestPool Failure
, then consult Debugging.
If you plan to run the Update 3 or Update 4 use case, then leave your domain running.
To remove the resources you have created in the samples, see Cleanup.