Learn how to deploy custom classes with the User Code Namespace
Context
In this tutorial, you’ll do the following:
- 
Deploy Hazelcast with userCodeNamespaces enabled. 
- 
Create a custom EntryListener class and package it into a JAR. 
- 
Upload the JAR file to cloud storage. 
- 
Apply a UserCodeNamespace resource, referencing the JAR in storage. 
- 
Create a Map resource with the EntryListener, setting userCodeNamespaces the same as the UserCodeNamespace object. 
Before you Begin
Step 1. Start the Hazelcast Cluster
- 
Create a license secret Create a secret with your Hazelcast Enterprise License. kubectl create secret generic hazelcast-license-key --from-literal=license-key=<hz-license-key>
- 
Create the Hazelcast Cluster Run the following command to create the Hazelcast cluster with Persistence enabled using External type. kubectl apply -f - <<EOF apiVersion: hazelcast.com/v1alpha1 kind: Hazelcast metadata: name: hazelcast spec: clusterSize: 1 repository: "docker.io/hazelcast/hazelcast-enterprise" version: "5.5.4" licenseKeySecretName: hazelcast-license-key userCodeNamespaces: {} EOF
- 
Check the Cluster Status Run the following commands to see the cluster status $ kubectl get hazelcast hazelcast NAME STATUS MEMBERS hazelcast Running 1/1
Step 2. Deploy the EntryListener JAR to Cloud Storage
In this step, you’ll build the EntryListener JAR from the tutorial’s GitHub repository, and upload it to your cloud provider.
- 
Clone the sample project. git clone https://github.com/hazelcast-guides/hazelcast-platform-operator-user-code-namespace.git cd hazelcast-platform-operator-user-code-namespacegit clone git@github.com:hazelcast-guides/hazelcast-platform-operator-user-code-namespace.git cd hazelcast-platform-operator-user-code-namespaceThe sample code for this tutorial is in the simple-entry-listener/src/main/java/com/hazelcast/tutorial/directory:
- 
Build the SimpleEntryListener JAR. mvn package -f ./simple-entry-listener
- 
Upload the SimpleEntryListener JAR to the storage blob/bucket of your cloud provider, replacing the placeholder values. aws s3 cp simple-entry-listener/target/simple-entry-listener-1.0-SNAPSHOT.jar s3://<BUCKET_NAME>gsutil cp simple-entry-listener/target/simple-entry-listener-1.0-SNAPSHOT.jar gs://<BUCKET_NAME>az storage blob upload --account-name <ACCOUNT_NAME> --container-name <CONTAINER_NAME> --file simple-entry-listener/target/simple-entry-listener-1.0-SNAPSHOT.jar
- 
Create a secret for your cloud storage by running one of the following commands. Remember to replace the placeholder values. kubectl create secret generic <SECRET-NAME> --from-literal=region=<region> \ --from-literal=access-key-id=<access-key-id> \ --from-literal=secret-access-key=<secret-access-key>kubectl create secret generic <SECRET-NAME> --from-file=google-credentials-path=<service_account_json_file>kubectl create secret generic <SECRET-NAME> \ --from-literal=storage-account=<storage-account> \ --from-literal=storage-key=<storage-key>
Step 3. Apply the UserCodeNamespace resource
- 
Apply the UserCodeNamespace resource Run the following command to create the UserCodeNamespace, referencing to the bucket where the EntryLister JAR is located. kubectl apply -f - <<EOF apiVersion: hazelcast.com/v1alpha1 kind: UserCodeNamespace metadata: name: my-ucn spec: hazelcastResourceName: hazelcast bucketConfig: secretName: <SECRET_NAME> bucketURI: <BUCKET_URI> EOF
- 
Check the status of the UserCodeNamespace resource Run the following command to check the status of the UserCodeNamespace resource $ kubectl get ucn my-ucn NAME STATUS my-ucn SuccessIt verifies that: - 
The user code namespaces called my-ucnis created.
- 
The jars in the bucket are downloaded into the members’ classpath. 
- 
The classes in the jars are added to the my-ucnnamespace.
 
- 
Step 4. Create the Map with the EntryListener
- 
Create the Map in a specific namespace Run the following command to create the Map with the SimpleEntryListener class in the my-ucnnamespace.kubectl apply -f - <<EOF apiVersion: hazelcast.com/v1alpha1 kind: Map metadata: name: my-map spec: hazelcastResourceName: hazelcast userCodeNamespace: my-ucn entryListeners: - className: com.hazelcast.tutorial.SimpleEntryListener EOF
- 
Check the status of the Map Run the following command to check the status of the Map $ kubectl get map my-map NAME STATUS my-map SuccessThe status of my-mapisSuccess, indicating that the map was successfully created with the user code namespacemy-ucnand includes one EntryListener class,com.hazelcast.tutorial.SimpleEntryListener.You can optionally put some entries to the map to observe the EntryListener in action. $ kubectl logs hazelcast-0 Entry Added:EntryEvent{entryEventType=ADDED, member=Member [10.80.2.23]:5702 - 237432e4-7a74-49ec-a2e5-d13ac9a8a41c this, name='my-map', key=gSMjgutLELKzZEEn, oldValue=null, value=LXqfGSOlYSIhMbTETLCNXgrYGbmdxCEpwmbPzmRkJjUCWUCu, mergingValue=null} Entry Added:EntryEvent{entryEventType=ADDED, member=Member [10.80.2.23]:5702 - 237432e4-7a74-49ec-a2e5-d13ac9a8a41c this, name='my-map', key=MehMxfDQQAzSlJHc, oldValue=null, value=GJTqmcmeSGPbRzQHjcSQDrQtttDxqwrFuginlqZRtxkUMCll, mergingValue=null} Entry Added:EntryEvent{entryEventType=ADDED, member=Member [10.80.2.23]:5702 - 237432e4-7a74-49ec-a2e5-d13ac9a8a41c this, name='my-map', key=YcSjQHklapAKVgZh, oldValue=null, value=QUmnTsqnTzivhROWpHlDujCuMwVnLzYSELwoNgWHkPEzwouL, mergingValue=null} Entry Added:EntryEvent{entryEventType=ADDED, member=Member [10.80.2.23]:5702 - 237432e4-7a74-49ec-a2e5-d13ac9a8a41c this, name='my-map', key=XeHNRdcizbNZQgZH, oldValue=null, value=SFuZPrNNDbhHCGwAHLQWZZVmTBLvCFcUAawGSKzyAetQOpEi, mergingValue=null} Entry Added:EntryEvent{entryEventType=ADDED, member=Member [10.80.2.23]:5702 - 237432e4-7a74-49ec-a2e5-d13ac9a8a41c this, name='my-map', key=mcPOBkUEmzBEkgXJ, oldValue=null, value=oTKCqSFoExFHuRKtzUcLjFdPbSPLihVBPfvafiQXppayJzom, mergingValue=null}
Step 6. Clean Up
To clean up the created resources remove the secrets and Hazelcast Custom Resources.
$ kubectl delete secret <external-bucket-secret-name>
$ kubectl delete secret hazelcast-license-key
$ kubectl delete hazelcast hazelcast