Context Service Objects
Context Service uses four ContextObject
types to store context data:
- Customer—Data about a specific customer. The customer type of
ContextObject
provides a way of linking personally identifiable information (PII) data with a customer ID. PII is personal data such as name and address, phone number, or a link to associated customer details in a different data source. - Request—Data about one or more customer interactions for a specific issue. The request type of
ContextObject
reflects the customer's view of an issue, indexes customer journey and interaction information, and is used to group related activities together. You must associate each request with a customer. - POD—Data that describes a specific customer interaction associated with a customer or request. The POD type of
ContextObject
is also known as an activity. Activities reflect each individual step in the customer journey as the customer seeks the fulfillment of their request. You can optionally associate an activity with a customer or a request. - Detail—Data that describes additional information about another
ContextObject
. The detail type ofContextObject
also contains the subtypesdetail.comment
anddetail.feedback
. You must associate each detail with either a request or an activity.
The Customer, Request, and Pod classes are deprecated. You cannot update or get requests created using the deprecated Request class.
These object types are accessed as ContextObject
objects. ContextObject
extends the ContextBean
class and is managed with the ContextServiceClient()
interface. You can use this interface to create and update objects stored in Context Service. If you are in lab mode, you can also delete objects.
Each individual
ContextObject
can store a maximum of 256KB.
Fields are used to define what kind of data is stored in objects. Objects can have multiple fieldsets assigned to them. You can use the fields and fieldsets available by default or create your own custom fields and fieldsets. For more information, see Base Fields and Fieldsets and Custom Fields and Fieldsets.
Encryption
Context Service provides client-side encryption so that sensitive data is not stored or transmitted in plain text. When you define a field, you specify how the field classifies data. You can classify data as:
- Unencrypted—Data is stored as plain text.
- Personally Identifiable Information (PII)—Data is PII, and is encrypted.
- Non-PII Encrypted—Data is not PII, and is encrypted.
For examples on how Context Service classifies default fields, see Base Fields and Fieldsets.
You can use the type differentiation of encrypted data for analysis. You can give different levels of access to different classifications of data. For example, you can run analytics on non-PII information that you still want to store as encrypted, and not allow access to the PII data associated with the non-PII data. You can also store unencrypted data for non-confidential objects to enable easier search.
Context Service does not prevent you from storing PII or confidential information in unencrypted fields. Make sure that your data is stored in the appropriate field with the correct classification.
Context Object Properties
Property | Description | Value | Usage |
---|---|---|---|
contributors | List of collaborators for a ContextObject . |
Automatically updated when a user creates or updates the ContextObject . You can also use the setNewContributor method to change the contributor added to the contributors list on the next save. |
Activity, Customer, Detail, Request |
created | Object creation time stamp. | Read-only, generated on object creation. | Activity, Customer, Detail, Request |
customerId | Unique identifier representing a customer type ContextObject . Used to link a ContextObject with a customer. |
|
Activity, Request |
dataElements | Data fields defined by the fieldsets assigned to this object. Fields classified as PII or Non-PII Encrypted are automatically encrypted. | User defined data. | Activity, Customer, Detail, Request |
fieldsets | Fieldsets define which fields apply to an object. Each object must have at least one fieldset assigned to it. | User defined fieldsets. | Activity, Customer, Detail, Request |
id | Unique ContextObject identifier. |
UUID generated on object creation. | Activity, Customer, Detail, Request |
lastUpdated | Time stamp of when the object was last updated. The lastUpdated value must match the database value before updating or saving an object for synchronization purposes. |
Read-only, automatically set when user updates an object. Users cannot set this property. | Activity, Customer, Detail, Request |
mediaType | User-defined media types. | Values are:
|
Activity |
parentId | Unique identifier representing a parent ContextObject . |
|
Activity, Detail |
state | ContextObject state. |
Values are:
|
Activity, Customer, Detail, Request |
tags | List of tags for an activity. | Optional property. User defined tags. | Activity |
type | Specifies the object type as a pod (activity), customer, request, or detail. | Values are:
ContextObjects can also use the subtypes:
|
Activity, Customer, Detail, Request |
Object State
Context Service uses object state to determine when contributors can modify customers, requests, and details.
You can modify the
pod
(activity) type ofContextObject
regardless of the object state. You can updateclosed
activities or setclosed
activities toactive
.
- Customer—State is
active
and cannot be set toclosed
. You can always update customers. - POD (activity)—State is either
active
orclosed
. You can always update activities regardless of the object state. - Request—State is either
active
orclosed
. You cannot update requests that are in aclosed
state or setclosed
requests toactive
. Context Service automatically closes each request 5 days after the request or any activities associated with the request are updated. - Detail—State is
closed
and cannot be set toactive
. You cannot update details.
You can use the Context Service SDK to set the state or return the current state of an object. Use the setState()
method on an activity or request to set the state as ContextObject.States.ACTIVE
or ContextObject.States.CLOSED
. Use the getState()
method on an object to return the object state.
Context Object Associations
Associate the different types of context information together to create a complete map of the customer journey.
You must specify which fieldsets
are used in any new object you create. create()
returns a
SDKUtils.getIdFromResponse(newlyCreatedPod)
returns the ID of the new object.
Each type of ContextObject
has different association restrictions:
- Request—You must associate requests with a
customer
typeContextObject
. Use thesetCustomerId()
method on a request to associate the request with a customer. Creating a request that isn't associated with a customer throws aninvalidInput.fieldRequired
error. - POD—You can optionally associate activities with a customer or a request. You can also associate activities with a customer and a request. Use the
setCustomerId()
method on an activity to associate the activity with a customer. Use thesetParentId()
method on an activity to associate the activity with a request.
Though you can create an activity that isn't associated with another
ContextObject
, connecting an activity with a customer and a request helps provide context to the customer interaction.
- Detail—You must associate details with either a
request
or apod
(activity) typeContextObject
. Use thesetParentId()
method on a detail with theid
of either arequest
or apod
(activity) typeContextObject
to associate the detail with a parentContextObject
. Creating a detail that isn't associated with either a request or an activity throws aninvalidInput.fieldRequired
error. - Customer—You cannot associate a customer with another
ContextObject
. Creating a customer that is associated with anotherContextObject
throws aninvalidRequest
error.
Create Objects
To create a new object, use ContextServiceClient().create()
with a specified type
of ContextObject
. The create()
method automatically creates the following object properties:
- id
- created
- lastUpdated
- contributors
- state
The default
state
value isactive
for customers, requests, and activities. The defaultstate
value isclosed
for details. For more information, see Object State.
Use the setFieldsets()
method to assign fieldsets to an object. Each object must have at least one fieldset assigned to it. You cannot add a field to dataElements
if that field isn't in any of the fieldsets assigned to the object. Use (Set<DataElement> dataElements)
to add fields to an object. You can also add multiple fields at a time to the object by defining the fields in a Java map. Use the helper function DataElementUtils.convertDataMapToSet()
to convert the Java map to a set. For more information on adding creating new fieldsets and adding fields to fieldsets, see Custom Fields and Fieldsets.
New objects must follow the restrictions on object associations. For more information, see Object Associations.
The create()
method returns a [ClientResponse](/cs-sdk-guide/
/com/cisco/thunderhead/client/ClientResponse.html) object. You can use the Context Service SDK helper utilities to retrieve the id
or the lastUpdated
value from the ClientResponse
object. For example, SDKUtils.getIdFromResponse(newlyCreatedObject)
returns the id
of a new object and SDKUtils.getLastUpdatedFromResponse(newlyCreatedObject)
returns the lastUpdated
date in RFC3339 format.
These examples show how to create new objects. The functions take an initialized contextServiceClient
as the input parameter and return the newly created object.
Copy/**
* Create a Customer with default fields and fieldsets.
* @param contextServiceClient an initialized ContextServiceClient
* @return a newly-created customer with the cisco.base.customer fieldset
*/
public static ContextObject createCustomerWithBaseFieldset(ContextServiceClient contextServiceClient) {
ContextObject customer = new ContextObject(ContextObject.Types.CUSTOMER);
customer.setDataElements(
DataElementUtils.convertDataMapToSet(
new HashMap<String, Object>() {{
put("Context_Work_Email", "john.doe@example.com");
put("Context_Work_Phone", "555-555-5555");
put("Context_First_Name", "John");
put("Context_Last_Name", "Doe");
put("Context_Street_Address_1", "123 Sesame Street");
put("Context_City", "Detroit");
put("Context_State", "MI");
put("Context_Country", "US");
put("Context_ZIP", "90210");
}}
)
);
customer.setFieldsets(Arrays.asList("cisco.base.customer"));
contextServiceClient.create(customer);
return customer;
}
/**
* Create a Request with default fields and fieldsets.
* @param contextServiceClient an initialized ContextServiceClient
* @param customer a pre-existing Customer object
* @return a newly-created request associated with the Customer, with the cisco.base.request fieldset
*/
public static ContextObject createRequestWithBaseFieldset(ContextServiceClient contextServiceClient, ContextObject customer) {
ContextObject request = new ContextObject(ContextObject.Types.REQUEST);
request.setDataElements(
DataElementUtils.convertDataMapToSet(
new HashMap<String, Object>() {{
put("Context_Description", "Request1 Description");
put("Context_Title", "Request1 Title");
}}
)
);
request.setFieldsets(Arrays.asList("cisco.base.request"));
request.setCustomerId(customer.getId());
contextServiceClient.create(request);
return request;
}
/**
* Create POD with default fields and fieldsets.
* @param contextServiceClient an initialized ContextServiceClient
* @return a newly-created pod with the cisco.base.pod fieldset
*/
public static ContextObject createPodWithBaseFieldset(ContextServiceClient contextServiceClient) {
ContextObject pod = new ContextObject(ContextObject.Types.POD);
pod.setDataElements(
DataElementUtils.convertDataMapToSet(
new HashMap<String, Object>() {{
put("Context_Notes", "Notes about this context.");
put("Context_POD_Activity_Link", "http://myservice.example.com/service/ID/xxxx");
}}
)
);
pod.setFieldsets(Arrays.asList("cisco.base.pod"));
contextServiceClient.create(pod);
return pod;
}
/**
* Create a POD with an associated request.
* @param contextServiceClient an initialized ContextServiceClient
* @param request a pre-existing Request object
* @return a pod associated with the Request
*/
public static ContextObject createPodWithRequest(ContextServiceClient contextServiceClient, ContextObject request) {
ContextObject pod = new ContextObject(ContextObject.Types.POD);
pod.setDataElements(
DataElementUtils.convertDataMapToSet(
new HashMap<String, Object>() {{
put("Context_Notes", "Notes about this context.");
put("Context_POD_Activity_Link", "http://myservice.example.com/service/ID/xxxx");
}}
)
);
pod.setFieldsets(Arrays.asList("cisco.base.pod"));
pod.setParentId(request.getId());
contextServiceClient.create(pod);
return pod;
}
/**
* Create a POD and associate a customer to the POD.
* @param contextServiceClient an initialized ContextServiceClient
* @param customer a pre-existing Customer object
* @return a POD associated with the Customer
*/
public static ContextObject createPodWithCustomer(ContextServiceClient contextServiceClient, ContextObject customer) {
ContextObject pod = new ContextObject(ContextObject.Types.POD);
pod.setDataElements(
DataElementUtils.convertDataMapToSet(
new HashMap<String, Object>() {{
put("Context_Notes", "Notes about this context.");
put("Context_POD_Activity_Link", "http://myservice.example.com/service/ID/xxxx");
}}
)
);
pod.setFieldsets(Arrays.asList("cisco.base.pod"));
pod.setCustomerId(customer.getId());
contextServiceClient.create(pod);
return pod;
}
/**
* Create detail.comment with default field and fieldsets
* @param contextServiceClient an initialized ContextServiceClient
* @param pod pre-existing Pod object
* @return a newly-created detail.comment associated with the Pod, and with cisco.base.comment fieldset
*/
public static ContextObject createCommentWithBaseFieldset(ContextServiceClient contextServiceClient, ContextObject pod) {
String type = ContextObject.Types.DETAIL + ".comment";
ContextObject comment = new ContextObject(type);
comment.setDataElements(
DataElementUtils.convertDataMapToSet(
new HashMap<String, Object>() {{
put("Context_Comment", "Detailed context comment.");
put("Context_Visible", true);
put("Context_DisplayName", "Display name");
}}
)
);
comment.setFieldsets(Arrays.asList("cisco.base.comment"));
comment.setParentId(pod.getId());
contextServiceClient.create(comment);
return comment;
}
/**
* Create detail.feedback with default field and fieldsets
* @param contextServiceClient an initialized ContextServiceClient
* @param pod pre-existing Pod object
* @return a newly-created detail.feedback associated with the Pod, and with cisco.base.comment fieldset
*/
public static ContextObject createFeedbackWithBaseFieldset(ContextServiceClient contextServiceClient, ContextObject pod) {
String type = ContextObject.Types.DETAIL + ".feedback";
ContextObject feedback = new ContextObject(type);
feedback.setDataElements(
DataElementUtils.convertDataMapToSet(
new HashMap<String, Object>() {{
put("cccRatingComments", "Detailed rating comments.");
put("cccRatingPoints", "Rating points");
}}
)
);
feedback.setFieldsets(Arrays.asList("cisco.base.rating"));
feedback.setParentId(pod.getId());
contextServiceClient.create(feedback);
return feedback;
}
Add New Contributor to a Context Object
A contributor is a machine or user that creates or modifies an object. The contributor properties include:
- contributorType—Value is either
MACHINE
orUSER
. - username—Read-only Cisco Common Identity client UUID.
- id—Contributor identifier as an optional string value.
By default, when a ContextObject
is created or updated the user or machine account name is added to the list of contributors. The setNewContributor()
method allows you to append a contributor ID (such as an agent ID) to a ContextObject
and specify the contributor type.
This example shows how to add a new contributor to an activity, using an initialized contextServiceClient
and a podId
as the input parameters. It returns the updated activity with the new contributor information.
Copy/**
* Add a new contributor to a POD.
* @param contextServiceClient an initialized ContextServiceClient
* @param podId
* @return the updated POD with the new contributor
*/
public static ContextObject addContributorToPod(ContextServiceClient contextServiceClient, UUID podId) {
ContextObject pod = contextServiceClient.getContextObject(ContextObject.Types.POD, podId.toString());
Contributor contributor = new Contributor(ContributorType.USER, "AgentId");
pod.setNewContributor(contributor);
contextServiceClient.update(pod);
return pod;
}
Update Objects
These examples show how to:
- Get an object using
ContextServiceClient.get()
. - Updated the returned object using
ContextServiceClient.update()
.
Use the object's most recent lastUpdated
value to pass back to update()
. By passing this value back to update()
, Context Service ensures that you are updating the most recent version of the object. Updating an object fails if you attempt to update an object without passing the most recent lastUpdated
property.
You don't need to set the
lastUpdated
field manually. ThelastUpdated
field is included when you get the object. When youupdate()
an object, unless you specifically called a set method on the property or modified theDataElement
values, all existing properties are set to the same value as when you received them.
You cannot update requests that are in the
closed
state. Context Service automatically closes each request 5 days after the request or any activities associated with the request are updated. You cannot update detail typeContextObjects
.
The functions take an initialized contextServiceClient
and the object id
as the input parameters and returns the updated object.
Copy/**
* Update a POD.
* @param contextServiceClient an initialized ContextServiceClient
* @param podId
* @return the updated POD
*/
public static ContextObject updatePod(ContextServiceClient contextServiceClient, UUID podId) {
ContextObject pod = contextServiceClient.getContextObject(ContextObject.Types.POD, podId.toString());
// Add a media type
pod.setMediaType(PodMediaType.SOCIAL);
// update DataElements
Map<String, Object> updateData = DataElementUtils.convertDataSetToMap(pod.getDataElements());
updateData.put("Context_Notes", "pod was modified");
pod.setDataElements(DataElementUtils.convertDataMapToSet(updateData));
// Send the update
contextServiceClient.update(pod);
return pod;
}
/**
* Update a Customer.
* @param contextServiceClient an initialized ContextServiceClient
* @param customerId
* @return the updated Customer
*/
public static ContextObject updateCustomer(ContextServiceClient contextServiceClient, UUID customerId) {
ContextObject customer = contextServiceClient.getContextObject(ContextObject.Types.CUSTOMER, customerId.toString());
Map<String, Object> updateData = DataElementUtils.convertDataSetToMap(customer.getDataElements());
updateData.put("Context_Street_Address_1", "333 Sesame Street");
customer.setDataElements(DataElementUtils.convertDataMapToSet(updateData));
contextServiceClient.update(customer);
return customer;
}
/**
* Update a Request.
* @param contextServiceClient an initialized ContextServiceClient
* @param requestId
* @return the updated Request
*/
public static ContextObject updateRequest(ContextServiceClient contextServiceClient, UUID requestId) {
ContextObject request = contextServiceClient.getContextObject(ContextObject.Types.REQUEST, requestId.toString());
Map<String, Object> updateData = DataElementUtils.convertDataSetToMap(request.getDataElements());
updateData.put("Context_Title", "Updated Context Title");
request.setDataElements(DataElementUtils.convertDataMapToSet(updateData));
contextServiceClient.update(request);
return request;
}
Delete Objects
This example shows how to delete an object by passing the object URL to ContextServiceClient().delete()
. You can only delete objects in lab mode. You cannot delete object in production mode.
Warning: Deletions are Permanent!
Copy/**
* Delete a ContextObject
* @param contextServiceClient an initialized ContextServiceClient
* @param object the ContextObject to be deleted
*/
public static void deleteContextObject(ContextServiceClient contextServiceClient, ContextObject object){
contextServiceClient.delete(object);
}
Flush Object Data
Use flush to purge all data before you set up your organization, or to clear data created during tests.
You must be in lab mode to use flush. You cannot flush object data in production mode.
To delete all data or to delete all data of a specific type of object, use flush()
with the ContextServiceClient
method of ContextObject
type:
contextServiceClient.flush(ContextObject.Types.POD)
contextServiceClient.flush(ContextObject.Types.CUSTOMER)
contextServiceClient.flush(ContextObject.Types.REQUEST)
contextServiceClient.flush(ContextObject.Types.DETAIL)
Flush is a non-blocking method and allows you to continue to perform other operations. This can potentially result in loss of data. Call waitForFlushComplete
to wait for the flush function to complete before executing other commands.
Flushing removes objects permanently.
This example shows how to flush all types of objects together. The example also executes a 30 second wait for each flush operation to complete before throwing an exception.
Copy/**
* Flush all entities (pods, request, customers) at once and wait for each flush to complete.
* Note: Flush is only supported in lab mode.
*
* @param contextServiceClient Context Service Client
* @throws InterruptedException, when an interrupt signal is caught during wait
* @throws TimeoutException, when flush is not complete and the timeout expires
*/
public static void flushAllEntities(ContextServiceClient contextServiceClient) throws InterruptedException, TimeoutException {
LOGGER.info("Flushing workgroup data...");
contextServiceClient.flush(ContextObject.Types.DETAIL + ".comment");
contextServiceClient.flush(ContextObject.Types.DETAIL + ".feedback");
contextServiceClient.flush(ContextObject.Types.POD);
contextServiceClient.flush(ContextObject.Types.REQUEST);
contextServiceClient.flush(ContextObject.Types.CUSTOMER);
waitForFlushComplete(contextServiceClient, ContextObject.Types.DETAIL + ".comment");
waitForFlushComplete(contextServiceClient, ContextObject.Types.DETAIL + ".feedback");
waitForFlushComplete(contextServiceClient, ContextObject.Types.POD);
waitForFlushComplete(contextServiceClient, ContextObject.Types.CUSTOMER);
waitForFlushComplete(contextServiceClient, ContextObject.Types.REQUEST);
LOGGER.info("Flushed workgroup data.");
}
/**
* waitForFlushComplete
* @param contextServiceClient the contextServiceClient
* @param contextObjectType the type of the ContextObject to be flushed
* @throws TimeoutException
*/
private static void waitForFlushComplete(ContextServiceClient contextServiceClient, String contextObjectType) throws TimeoutException {
FlushStatusBean status;// Use SDK to wait for flush to complete. In this case, allow up to 30 seconds...
status = contextServiceClient.waitForFlushComplete(contextObjectType, MAX_FLUSH_WAIT_IN_SECONDS);
if (status.isCompleted()) {
LOGGER.info("Flush of " + contextObjectType + "s complete. Flushed " + status.getNumberFlushed() + " " + contextObjectType + "s.");
} else {
LOGGER.info("Flush of " + contextObjectType + "s not complete. Flushed " + status.getNumberFlushed() + " " + contextObjectType + "s." + (!StringUtils.isEmpty(status.getMessage()) ? status.getMessage() : ""));
throw new TimeoutException();
}
}
This example shows how to flush all activity data.
Copy/**
* Note: flush is only supported in "lab" (not "production") mode.
*
* @param contextServiceClient an initialized Context Service Client
* @throws InterruptedException thrown if an interrupt signal is caught during the wait
* @throws TimeoutException thrown if a flush has not completed when the timeout expires
*/
public static void flushPods(ContextServiceClient contextServiceClient) throws InterruptedException, TimeoutException {
flushContextObject(contextServiceClient, ContextObject.Types.POD);
}