Zero Downtime Migrations

Before StartYou should have NO virtualservice, destinationrule, gateway or policy (in tutorial namespace) kubectl get virtualservice kubectl get destinationrule kubectl get gateway kubectl get policyif so run:
  1. ./scripts/clean.sh
Also, you need to undeploy any recommendation service (v1, v2, v3) that you might have deployed on the cluster.To undeploy them just run:
  1. oc delete all -l app=recommendation -n tutorialorkubectl delete all -l app=recommendation -n tutorial
Wait until all recommendation serivces are down.
  1. oc get pods -n tutorialorkubectl get pods -n tutorialNAME READY STATUS RESTARTS AGEcustomer-3600192384-fpljb 2/2 Running 0 17mpreference-243057078-8c5hz 2/2 Running 0 15m
Old Versions of customer and preferenceTo run this section you need to deploy the latest customer and preference versions, if you already have these old versions of customer and preference, deploy them again with latest sources following Deploy Microservices.

Deploy recommendation:v4

Deploy PostgreSQL database

The first thing you need to do is deploy a PostgreSQL database server.

  1. cd recommendation/java/vertx
  2. oc apply -f <(istioctl kube-inject -f ../../kubernetes/PostgreSQL-deployment.yml) -n tutorial
  3. or
  4. kubectl apply -f <(istioctl kube-inject -f ../../kubernetes/PostgreSQL-deployment.yml) -n tutorial
  5. oc create -f ../../kubernetes/PostgreSQL-service.yml -n tutorial
  6. or
  7. kubectl create -f ../../kubernetes/PostgreSQL-service.yml -n tutorial
  8. # Wait until PotsgresSQL deployed
  9. oc get pods -w -n tutorial
  10. or
  11. kubectl get pods -w -n tutorial

Inspecting Database Changes

I recommend that every time you deploy a new recommendation service version or you do a POST call, you inspect how the database (recommendation table) has changed.

To do it, you just need to go inside into the postgres container and use psql tool.Open a new terminal window and run next commands:

  1. oc get pods
  2. or
  3. kubectl get pods
  4. NAME READY STATUS RESTARTS AGE
  5. customer-7dcd544ff9-5j6ml 2/2 Running 0 22m
  6. postgres-6cc7c8bbd5-jqw8r 2/2 Running 0 31m
  7. preference-v1-7f7ddf6c4-fhjtw 2/2 Running 0 21m
  8. kubectl exec -ti postgres-6cc7c8bbd5-jqw8r -c postgres /bin/bash

Then, when you are inside the container, you can inspect database changes:

  1. psql -U admin recommendation
  2. recommendation=# select * from recommendation;
  3. id | name
  4. ----+--------------------------
  5. 1 | Star Wars: A New Hope
  6. 2 | Star Trek: First Contact
  7. (2 rows)

Create recommendation:v4

To create recommendation v4, we need to change one line in pom.xml) of project, and change configuration part from vertx-maven-plugin:

Before:

pom.xml

  1. <configuration>
  2. <verticle>com.redhat.developer.demos.recommendation.RecommendationVerticle</verticle>
  3. </configuration>

After:

pom.xml

  1. <configuration>
  2. <verticle>com.redhat.developer.demos.recommendation.RecommendationPersistenceVerticle</verticle>
  3. </configuration>

Docker build (if you have access to Docker daemon)

  1. mvn clean package
  2. docker build -t example/recommendation:v4 .
  3. docker images | grep recommendation
  4. example/recommendation v4 b23e37349009 1 minutes ago 438MB
  5. example/recommendation v2 c31e399a9628 5 minutes ago 438MB
  6. example/recommendation v1 f072978d9cf6 8 minutes ago 438MB
We have a 4th Deployment to manage the v4 version of recommendation.
  1. oc apply -f <(istioctl kube-inject -f ../../kubernetes/Deployment-v4.yml) -n tutorial
  2. oc get pods -w -n tutorial
  3. or
  4. kubectl apply -f <(istioctl kube-inject -f ../../kubernetes/Deployment-v4.yml) -n tutorial
  5. kubectl get pods -w -n tutorial
  6. oc create -f ../../kubernetes/Service.yml
  7. or
  8. kubectl create -f ../../kubernetes/Service.yml

OpenShift S2I strategy (if you DON’T have access to Docker daemon)

  1. mvn clean package -f recommendation/java/vertx
  2. oc new-app -l app=recommendation,version=v4 --name=recommendation-v4 --context-dir=recommendation/java/vertx -e JAEGER_SERVICE_NAME=recommendation JAEGER_ENDPOINT=http://jaeger-collector.istio-system.svc:14268/api/traces JAEGER_PROPAGATION=b3 JAEGER_SAMPLER_TYPE=const JAEGER_SAMPLER_PARAM=1 JAVA_OPTIONS='-Xms128m -Xmx256m -Djava.net.preferIPv4Stack=true' fabric8/s2i-java~https://github.com/redhat-developer-demos/istio-tutorial -o yaml > recommendation-v4.yml
  3. oc apply -f <(istioctl kube-inject -f recommendation-v4.yml) -n tutorial
  4. oc cancel-build bc/recommendation-v4 -n tutorial
  5. oc delete svc/recommendation-v4 -n tutorial
  6. oc start-build recommendation-v4 --from-dir=. --follow -n tutorial

Wait for v4 to be deployed

Wait for those pods to show "2/2", the istio-proxy/envoy sidecar is part of that pod

  1. NAME READY STATUS RESTARTS AGE
  2. customer-3600192384-fpljb 2/2 Running 0 17m
  3. preference-243057078-8c5hz 2/2 Running 0 15m
  4. recommendation-v4-60483540-9snd9 2/2 Running 0 12m

and test the customer endpoint

  1. curl customer-tutorial.$(minishift ip).nip.io
  2. recommendation v4 [Star Wars: A New Hope,Star Trek: First Contact] from '60483540-9snd9': 1

What you are getting here is a list of recommendations (every time will be the same) which are selected from the database, so it means that any change on the database is reflected to this query.

For example, run next command to add a new recommendation:

  1. curl -H "Content-type: text/plain" -X POST --data "Avengers: Infinity War" customer-tutorial.$(minishift ip).nip.io
  2. 3
If you don’t see an integer but a normal GET (customer ⇒ preference ⇒ recommendation v4 [Star Wars: A New Hope,Star Trek: First Contact] from '6d4b86c9fb-ph8rm': 2) this is because you have old versions of customer and preference services deployed.

And make a new request:

  1. curl customer-tutorial.$(minishift ip).nip.io
  2. recommendation v4 [Star Wars: A New Hope,Star Trek: First Contact, Avengers: Infinity War] from '60483540-9snd9': 2

Start the migration

What we want to do is one of the most complex operations in terms of database migration, and this is changing the name of a column.The same process is used for example if you need to change a data type, and it is similar in case of having to add new columns or tables.

Flyway

Flyway is a version control for your database.It allows you to evolute your database schema (and data) with ease and pleasure.

Flyway allows you to have your database migration files altogether with your code.In summary, any SQL file placed following Flyway_ naming convention at src/main/resources/db/migration are executed against a configured database if it has not applied before.

And this is the solution used in the recommendation service for dealing with database migrations.

The steps we are going to follow for the migration is by doing 3 versions of the service:

For sake of simplicity we are going to change the major number of the version, but in a real case, you’ll make it using minor/patch versions.
  • Add a new column and make the new service read from the old column and write to both.

  • Copy old data to the new column and code reads from the new column and writes to both.

  • The code reads and writes from the new column.

You can create subversions (i.e one version for adding the column, another for making the new service read from old column and write to both) depending on your release process.
It is important to follow these steps (no shortcuts) to make your application safe to any rollback in case of an error in the newer version.

So let’s see the process of updating the column named name to movie_name.

Recommendation:v5

The first thing to do before releasing recommendation v5 is to add the new column (which would be the final name, in this case, movie_name).To do it execute next command on a terminal:

  1. cp src/main/sql/V2__Add_movie_column_in_recommendation_table.sql src/main/resources/db/migration/V2__Add_movie_column_in_recommendation_table.sql

And then update the recommendation service to a newer version and to write new values to both columns.

  1. private static final String RESPONSE_STRING_FORMAT = "recommendation v5 from '%s': %d\n";

Open RecommendationPersistenceVerticle class and change start method form:

com.redhat.developer.demos.recommendation.RecommendationPersistenceVerticle

  1. router.post("/").handler(this::addRecommendation);
  2. // router.post("/").handler(this::addRecommendationToBothColumns);

to

com.redhat.developer.demos.recommendation.RecommendationPersistenceVerticle

  1. // router.post("/").handler(this::addRecommendation);
  2. router.post("/").handler(this::addRecommendationToBothColumns);

And then let’s build the new version and deploy it to the cluster.

Docker build (if you have access to Docker daemon)

  1. mvn clean package
  2. docker build -t example/recommendation:v5 .
  3. docker images | grep recommendation
  4. example/recommendation v5 a84563734376 1 minutes ago 438MB
  5. example/recommendation v4 b23e37349009 1 minutes ago 438MB
  6. example/recommendation v2 c31e399a9628 5 minutes ago 438MB
  7. example/recommendation v1 f072978d9cf6 8 minutes ago 438MB
We have a 5th Deployment to manage the v4 version of recommendation.
  1. oc apply -f <(istioctl kube-inject -f ../../kubernetes/Deployment-v5.yml) -n tutorial
  2. oc get pods -w -n tutorial
  3. or
  4. kubectl apply -f <(istioctl kube-inject -f ../../kubernetes/Deployment-v5.yml) -n tutorial
  5. kubectl get pods -w -n tutorial

OpenShift S2I strategy (if you DON’T have access to Docker daemon)

  1. mvn clean package -f recommendation/java/vertx
  2. oc new-app -l app=recommendation,version=v5 --name=recommendation-v5 --context-dir=recommendation/java/vertx -e JAEGER_SERVICE_NAME=recommendation JAEGER_ENDPOINT=http://jaeger-collector.istio-system.svc:14268/api/traces JAEGER_PROPAGATION=b3 JAEGER_SAMPLER_TYPE=const JAEGER_SAMPLER_PARAM=1 JAVA_OPTIONS='-Xms128m -Xmx256m -Djava.net.preferIPv4Stack=true' fabric8/s2i-java~https://github.com/redhat-developer-demos/istio-tutorial -o yaml > recommendation-v5.yml
  3. oc apply -f <(istioctl kube-inject -f recommendation-v5.yml) -n tutorial
  4. oc cancel-build bc/recommendation-v5 -n tutorial
  5. oc delete svc/recommendation-v5 -n tutorial
  6. oc start-build recommendation-v5 --from-dir=. --follow -n tutorial

Wait for v5 to be deployed

Wait for those pods to show "2/2", the istio-proxy/envoy sidecar is part of that pod

  1. NAME READY STATUS RESTARTS AGE
  2. customer-3600192384-fpljb 2/2 Running 0 17m
  3. preference-243057078-8c5hz 2/2 Running 0 15m
  4. recommendation-v4-60483540-9snd9 2/2 Running 0 12m
  5. recommendation-v5-00979354-89fga 2/2 Running 0 11m

Blue-Green Deployment between v4 and v5

Now we can start the release process of recommendation v5.Let’s redirect all traffic to v4.

  1. istioctl create -f ../../../istiofiles/destination-rule-recommendation-v4-v5-v6-v7.yml -n tutorial
  2. istioctl create -f ../../../istiofiles/virtual-service-recommendation-v4.yml -n tutorial
  1. curl customer-tutorial.$(minishift ip).nip.io
  2. recommendation v4 [Star Wars: A New Hope,Star Trek: First Contact, Avengers: Infinity War] from '60483540-9snd9': 2

Now, let’s redirect traffic to v5:

  1. istioctl replace -f ../../../istiofiles/virtual-service-recommendation-v5.yml -n tutorial

And apply some requests:

  1. curl customer-tutorial.$(minishift ip).nip.io
  2. recommendation v5 [Star Wars: A New Hope,Star Trek: First Contact, Avengers: Infinity War] from '00979354-89fga': 1
  3. curl -H "Content-type: text/plain" -X POST --data "Frozen" customer-tutorial.$(minishift ip).nip.io
  4. 3
  5. curl customer-tutorial.$(minishift ip).nip.io
  6. recommendation v5 [Star Wars: A New Hope,Star Trek: First Contact, Avengers: Infinity War, Frozen] from '00979354-89fga': 2

What’s happening if we find some problems in v5 ? We just need to redirect traffic back to v4.

  1. istioctl replace -f istiofiles/virtual-service-recommendation-v4.yml -n tutorial
  1. curl customer-tutorial.$(minishift ip).nip.io
  2. recommendation v4 [Star Wars: A New Hope,Star Trek: First Contact, Avengers: Infinity War, Frozen] from '60483540-9snd9': 3

Notice that even though, it is the old version, the content added during v5 was released is still available and no data lost has ocurred.Next step (executed by DB administrator) could be just removing the movie_name column.

But let’s suppose that v5 has no errors and it is going to be the correct release:

  1. istioctl replace -f istiofiles/virtual-service-recommendation-v5.yml -n tutorial

And we can undeploy the recommendation v4 service from the cluster:

  1. oc delete all -l app=recommendation,version=v4
  2. or
  3. kubectl delete all -l app=recommendation,version=v4

Recommendation:v6

The first thing to do before releasing recommendation v6 is to copy old data (name column) to the new column (movie_name).Usually, if the column contains a lot of entries, you’ll do it using a batch process, but for the sake of simplicity, a simple SQL update is executed in this case.To do it execute next command on a terminal:

  1. cp src/main/sql/V3__Update_recommendation_data.sql src/main/resources/db/migration/V3__Update_recommendation_data.sql

And then update code so the reads are happening from the new column and write to both.

  1. private static final String RESPONSE_STRING_FORMAT = "recommendation v6 from '%s': %d\n";

Open RecommendationPersistenceVerticle class and change getRecommendationsFromDb method form:

com.redhat.developer.demos.recommendation.RecommendationPersistenceVerticle

  1. final List<String> recommendations = findRecommendation(resultSet);
  2. // final List<String> recommendations = findRecommendationNew(resultSet);

to

com.redhat.developer.demos.recommendation.RecommendationPersistenceVerticle

  1. // final List<String> recommendations = findRecommendation(resultSet);
  2. final List<String> recommendations = findRecommendationNew(resultSet);

And then let’s build the new version and deploy it to the cluster.

Docker build (if you have access to Docker daemon)

  1. mvn clean package
  2. docker build -t example/recommendation:v6 .
  3. docker images | grep recommendation
  4. example/recommendation v6 345bb6773434 1 minutes ago 438MB
  5. example/recommendation v5 a84563734376 1 minutes ago 438MB
  6. example/recommendation v4 b23e37349009 1 minutes ago 438MB
  7. example/recommendation v2 c31e399a9628 5 minutes ago 438MB
  8. example/recommendation v1 f072978d9cf6 8 minutes ago 438MB
We have a 6th Deployment to manage the v4 version of recommendation.
  1. oc apply -f <(istioctl kube-inject -f ../../kubernetes/Deployment-v6.yml) -n tutorial
  2. oc get pods -w -n tutorial
  3. or
  4. kubectl apply -f <(istioctl kube-inject -f ../../kubernetes/Deployment-v6.yml) -n tutorial
  5. kubectl get pods -w -n tutorial

OpenShift S2I strategy (if you DON’T have access to Docker daemon)

  1. mvn clean package -f recommendation/java/vertx
  2. oc new-app -l app=recommendation,version=v6 --name=recommendation-v6 --context-dir=recommendation/java/vertx -e JAEGER_SERVICE_NAME=recommendation JAEGER_ENDPOINT=http://jaeger-collector.istio-system.svc:14268/api/traces JAEGER_PROPAGATION=b3 JAEGER_SAMPLER_TYPE=const JAEGER_SAMPLER_PARAM=1 JAVA_OPTIONS='-Xms128m -Xmx256m -Djava.net.preferIPv4Stack=true' fabric8/s2i-java~https://github.com/redhat-developer-demos/istio-tutorial -o yaml > recommendation-v6.yml
  3. oc apply -f <(istioctl kube-inject -f recommendation-v6.yml) -n tutorial
  4. oc cancel-build bc/recommendation-v6 -n tutorial
  5. oc delete svc/recommendation-v6 -n tutorial
  6. oc start-build recommendation-v6 --from-dir=. --follow -n tutorial

Wait for v6 to be deployed

Wait for those pods to show "2/2", the istio-proxy/envoy sidecar is part of that pod

  1. NAME READY STATUS RESTARTS AGE
  2. customer-3600192384-fpljb 2/2 Running 0 17m
  3. preference-243057078-8c5hz 2/2 Running 0 15m
  4. recommendation-v5-00979354-89fga 2/2 Running 0 11m
  5. recommendation-v6-98b29894-64g45 2/2 Running 0 11m

Blue-Green Deployment between v5 and v6

Now, let’s redirect traffic to v6:

  1. istioctl replace -f istiofiles/virtual-service-recommendation-v6.yml -n tutorial

And apply some requests:

  1. curl customer-tutorial.$(minishift ip).nip.io
  2. recommendation v6 [Star Wars: A New Hope,Star Trek: First Contact, Avengers: Infinity War, Frozen] from '98b29894-64g45': 3
  3. curl -H "Content-type: text/plain" -X POST --data "The Lord Of The Rings: The Fellowship of the Ring" customer-tutorial.$(minishift ip).nip.io
  4. 5
  5. curl customer-tutorial.$(minishift ip).nip.io
  6. recommendation v6 [Star Wars: A New Hope,Star Trek: First Contact, Avengers: Infinity War, Frozen, The Lord Of The Rings: The Fellowship of the Ring] from '98b29894-64g45': 2

What’s happening if we find some problems in v6 ? We just need to redirect traffic back to v5.

  1. istioctl replace -f istiofiles/virtual-service-recommendation-v5.yml -n tutorial
  1. curl customer-tutorial.$(minishift ip).nip.io
  2. recommendation v5 [Star Wars: A New Hope,Star Trek: First Contact, Avengers: Infinity War, Frozen, The Lord Of The Rings: The Fellowship of the Ring] from '00979354-89fga': 3

So again no data lost and rolling back the service has no consequences.

But let’s suppose that v6 has no errors and it is going to be the correct release:

  1. istioctl replace -f istiofiles/virtual-service-recommendation-v6.yml -n tutorial

And we can undeploy the recommendation v5 service from the cluster:

  1. oc delete all -l app=recommendation,version=v5
  2. or
  3. kubectl delete all -l app=recommendation,version=v5

Recommendation:v7

The last thing to do is just write every time to the new column movie_name and not both.Also, it implies removing the null constraint and add it to the new column.

  1. cp src/main/sql/V4__Update_movie_name_constraints.sql src/main/resources/db/migration/V4__Update_movie_name_constraints.sql
  1. private static final String RESPONSE_STRING_FORMAT = "recommendation v7 from '%s': %d\n";

Open RecommendationPersistenceVerticle class and change getRecommendationsFromDb method form:

com.redhat.developer.demos.recommendation.RecommendationPersistenceVerticle

  1. router.post("/").handler(this::addRecommendationToBothColumns);
  2. // router.post("/").handler(this::addRecommendationToNewColumn);

to

com.redhat.developer.demos.recommendation.RecommendationPersistenceVerticle

  1. // router.post("/").handler(this::addRecommendationToBothColumns);
  2. router.post("/").handler(this::addRecommendationToNewColumn);

And then let’s build the new version and deploy it to the cluster.

Docker build (if you have access to Docker daemon)

  1. mvn clean package
  2. docker build -t example/recommendation:v7 .
  3. docker images | grep recommendation
  4. example/recommendation v7 f449867a2342 2 minutes ago 438MB
  5. example/recommendation v6 345bb6773434 3 minutes ago 438MB
  6. example/recommendation v5 a84563734376 8 minutes ago 438MB
  7. example/recommendation v4 b23e37349009 9 minutes ago 438MB
  8. example/recommendation v2 c31e399a9628 12 minutes ago 438MB
  9. example/recommendation v1 f072978d9cf6 15 minutes ago 438MB
We have a 7th Deployment to manage the v4 version of recommendation.
oc apply -f <(istioctl kube-inject -f ../../kubernetes/Deployment-v7.yml) -n tutorial
oc get pods -w -n tutorial

or

kubectl apply -f <(istioctl kube-inject -f ../../kubernetes/Deployment-v7.yml) -n tutorial
kubectl get pods -w -n tutorial

OpenShift S2I strategy (if you DON’T have access to Docker daemon)

mvn clean package -f recommendation/java/vertx
oc new-app -l app=recommendation,version=v7 --name=recommendation-v7 --context-dir=recommendation/java/vertx -e JAEGER_SERVICE_NAME=recommendation JAEGER_ENDPOINT=http://jaeger-collector.istio-system.svc:14268/api/traces JAEGER_PROPAGATION=b3 JAEGER_SAMPLER_TYPE=const JAEGER_SAMPLER_PARAM=1 JAVA_OPTIONS='-Xms128m -Xmx256m -Djava.net.preferIPv4Stack=true' fabric8/s2i-java~https://github.com/redhat-developer-demos/istio-tutorial -o yaml  > recommendation-v7.yml
oc apply -f <(istioctl kube-inject -f recommendation-v7.yml) -n tutorial
oc cancel-build bc/recommendation-v7 -n tutorial
oc delete svc/recommendation-v7 -n tutorial
oc start-build recommendation-v7 --from-dir=. --follow -n tutorial

Wait for v7 to be deployed

Wait for those pods to show "2/2", the istio-proxy/envoy sidecar is part of that pod

NAME                                  READY     STATUS    RESTARTS   AGE
customer-3600192384-fpljb             2/2       Running   0          17m
preference-243057078-8c5hz           2/2       Running   0          15m
recommendation-v6-98b29894-64g45     2/2       Running   0          11m
recommendation-v7-bb452a56-45tg2     2/2       Running   0          10m

Blue-Green Deployment between v6 and v7

Now, let’s redirect traffic to v7:

istioctl replace -f istiofiles/virtual-service-recommendation-v7.yml -n tutorial

And apply some requests:

curl customer-tutorial.$(minishift ip).nip.io
recommendation v7 [Star Wars: A New Hope,Star Trek: First Contact, Avengers: Infinity War, Frozen, The Lord Of The Rings: The Fellowship of the Ring] from 'bb452a56-45tg2': 4

curl -H "Content-type: text/plain" -X POST --data "Howl's Moving Castle" customer-tutorial.$(minishift ip).nip.io
6

curl customer-tutorial.$(minishift ip).nip.io
recommendation v7 [Star Wars: A New Hope,Star Trek: First Contact, Avengers: Infinity War, Frozen, The Lord Of The Rings: The Fellowship of the Ring, Howl's Moving Castle] from 'bb452a56-45tg2': 5

What’s happening if we find some problems in v7 ? We just need to redirect traffic back to v6.

istioctl replace -f istiofiles/virtual-service-recommendation-v6.yml -n tutorial
curl customer-tutorial.$(minishift ip).nip.io

curl customer-tutorial.$(minishift ip).nip.io
recommendation v6 [Star Wars: A New Hope,Star Trek: First Contact, Avengers: Infinity War, Frozen, The Lord Of The Rings: The Fellowship of the Ring, Howl's Moving Castle] from '98b29894-64g45': 6

curl -H "Content-type: text/plain" -X POST --data "The Pink Panther" customer-tutorial.$(minishift ip).nip.io
7

Now v7 is fixed and released again:

istioctl replace -f istiofiles/virtual-service-recommendation-v7.yml -n tutorial
curl customer-tutorial.$(minishift ip).nip.io
recommendation v6 [Star Wars: A New Hope,Star Trek: First Contact, Avengers: Infinity War, Frozen, The Lord Of The Rings: The Fellowship of the Ring, Howl's Moving Castle, The Pink Panther] from '98b29894-64g45': 7

So no data lose, every step we follow is safe, and at any time we are able to roll back to last known working version without any problem and when the new version is released again, everything still works.

Final Step

The final step that should be done by a DB administrator for example when maintenance window is set, and it is to delete the old column since the new version of the service is not using it anymore for reading nor for writing.Keep in mind that this is a destructive operation so, it should be taken with care.

Cleanup

oc delete all -l app=recommendation
or
kubectl delete all -l app=recommendation

oc delete all -l app=postgres
or
kubectl delete all -l app=postgres

istioctl delete -f istiofiles/destination-rule-recommendation-v4-v5-v6-v7.yml -n tutorial
istioctl create -f istiofiles/virtual-service-recommendation-v7.yml -n tutorial

Then let’s redeploy recommendation v1 and v2.

cd recommendation/java/vertx

oc apply -f <(istioctl kube-inject -f ../../kubernetes/Deployment-v1.yml) -n tutorial
or
kubectl apply -f <(istioctl kube-inject -f ../../kubernetes/Deployment-v1.yml) -n tutorial

oc apply -f <(istioctl kube-inject -f ../../kubernetes/Deployment-v2.yml) -n tutorial
or
kubectl apply -f <(istioctl kube-inject -f ../../kubernetes/Deployment-v2.yml) -n tutorial

oc create -f ../../kubernetes/Service.yml
oc get pods -w
or
kubectl create -f ../../kubernetes/Service.yml
kubectl get pods -w

If you want to rollback the code of recommendation service to initial stages, you need to do next changes:

  • Rollback code changes in RecommendationPersistenceVerticle class.

From:

com.redhat.developer.demos.recommendation.RecommendationPersistenceVerticle

// final List<String> recommendations = findRecommendation(resultSet);
final List<String> recommendations = findRecommendationNew(resultSet);

To:

com.redhat.developer.demos.recommendation.RecommendationPersistenceVerticle

final List<String> recommendations = findRecommendation(resultSet);
// final List<String> recommendations = findRecommendationNew(resultSet);

And from:

com.redhat.developer.demos.recommendation.RecommendationPersistenceVerticle

// router.post("/").handler(this::addRecommendation);
// router.post("/").handler(this::addRecommendationToBothColumns);
router.post("/").handler(this::addRecommendationToNewColumn);

To:

com.redhat.developer.demos.recommendation.RecommendationPersistenceVerticle

router.post("/").handler(this::addRecommendation);
router.post("/").handler(this::addRecommendationToBothColumns);
// router.post("/").handler(this::addRecommendationToNewColumn);

And from:

com.redhat.developer.demos.recommendation.RecommendationPersistenceVerticle

private static final String RESPONSE_STRING_FORMAT = "recommendation v7 from '%s': %d\n";

To:

com.redhat.developer.demos.recommendation.RecommendationPersistenceVerticle

private static final String RESPONSE_STRING_FORMAT = "recommendation v4 from '%s': %d\n";
  • Remove next SQL scripts:
rm src/main/resources/db/migration/V2__Add_movie_column_in_recommendation_table.sql
rm src/main/resources/db/migration/V3__Update_recommendation_data.sql
rm src/main/resources/db/migration/V4__Update_movie_name_constraints.sql
  • Set correct verticle:

From:

pom.xml

<configuration>
    <verticle>com.redhat.developer.demos.recommendation.RecommendationPersistenceVerticle</verticle>
</configuration>

To:

pom.xml

<configuration>
    <verticle>com.redhat.developer.demos.recommendation.RecommendationVerticle</verticle>
</configuration>