Derivatives of FunctionalService
Derivatives of FunctionalService interface facilitates creation of functional implementation of standard services. Functional service is just an object with a public method which takes a certain input and generates the desired output.
Simple search (simple-search)
The following are the specialized interfaces and classes available for simple-search service:
com.hcl.unica.system.integration.service.search.SearchServiceThe
com.example.service.functional.ExampleSimpleSearchServiceclass in theasset-integration-starterproject is a quick starter implementation for the Functionalsimple-search service. It extends from thecom.hcl.unica.system.integration.service.search.SearchServiceclass.The
SearchServiceclass implements theFunctionalServiceinterface and defines theSearchRequestclass and theContentPageclass to be the type arguments RQ & RS respectively for the FunctionalService. Thus, the object of theSearchRequestbecomes an input to all thesimple-searchservices and theContentPageis expected as an output on completion of the service.The plugin must extend its
simple-searchimplementation from thecom.hcl.unica.system.integration.service.search.SearchServiceclass to be recognized as asimple-searchservice by the Content Integration Framework (RESTful counterpart discussed in earlier section is also a valid choice to extend from for thesimple-searchservices implemented using RESTful approach).The
SearchServiceextends from thecom.hcl.unica.system.integration.service.search.AbstractSearchServiceabstract class. It introduces one more method, namedgetSupportedContentTypes. For more information on the method, see Derivatives of RestService.
Resource loader (resource-loader)
The following are the specialized interfaces and classes available for the resource-loader service:
com.hcl.unica.system.integration.service.resourceloader.WebResourceLoaderServiceThecom.example.service.functional.ExampleResourceLoaderServiceclass in asset-integration-starter project is a quick starter implementation for Functionalresource-loaderservice. It extends from the following class:com.hcl.unica.system.integration.service.resourceloader.WebResourceLoaderServiceThe
WebResourceLoaderServiceclass implements theFunctionalServiceinterface and defines theResourceRequestand theHttpResponsetypes to be the type arguments RQ & RS, respectively, for theFunctionalService. Thus, the object of theResourceRequestbecomes an input to all theresource-loaderservices and theHttpResponseis expected as an output on completion of the service (the same input and output types are used for RESTful counterpart of the resource-loader). For more information onResourceRequest&HttpResponsetypes, see Derivatives of RestService.The plugin must extend its
resource-loaderimplementation from thecom.hcl.unica.system.integration.service.resourceloader.WebResourceLoaderServiceservice to be recognized as aresource-loaderservice by the Content Integration Framework (HTTP counterpart discussed in the earlier section is also a valid choice to extend from for theresource-loaderservices implemented using the HTTP approach).The WebResourceLoaderService extends from the following class:com.hcl.unica.system.integration.service.resourceloader. AbstractWebResourceLoaderServiceFor more information about this class, see Derivatives of RestService.
List content categories (list-content-categories)
The following are the specialized interfaces and classes available for list-content-categories service:
com.hcl.unica.system.integration.service.content.categories.list.ContentCategoriesListServicePlugin can alternatively choose Functional approach to implement
list-content-categoriesservice by extending the implementation fromContentCategoriesListServiceclass. TheContentCategoriesListServiceclass implements theFunctionalServiceinterface and mandates theContentCategoryListRequestand theList<ContentCategory>classes to be the type arguments RQ and RS respectively for theFunctionalService. Thus, the object of theContentCategoryListRequestbecomes an input to thelist-content-categoriesservice and the object of List<ContentCategory> type is expected as an output on completion of the service.ContentCategoryListRequestshould be consulted for parent category ID & folder ID to fetch categories belonging to specific parent category and/or to parent folder. As of current implementation of Content Integration Framework, parent (category) ID is always null since only one level of category list is supported. However, if categories are organized in folders &list-content-categoriesservice considers folder ID while listing categories, then Content Integration Framework can deal with navigable folder list iflist-category-foldersservice is also implemented.- The plugin must extend its list-content-categories implementation from the
com.hcl.unica.system.integration.service.content.categories.list.ContentCategoriesListServiceclass to be recognized as a validlist-content-categoriesservice by the Content Integration Framework (RESTful counterpart discussed in earlier section is also a valid choice to extend from).ContentCategoriesListServiceextends fromAbstractContentCategoriesListServiceclass. Details ofAbstractContentCategoriesListServiceclass are covered in the Derivatives of RestService topic.
List folders (list-folders)
The following are the specialized interfaces and classes available for list-folders service:
com.hcl.unica.system.integration.service.folder.list.FolderListServicePlugin can alternatively choose Functional approach to implement
list-foldersservice by extending the implementation fromFolderListServiceclass. TheFolderListServiceclass implements theFunctionalServiceinterface and mandates theFolderListRequestand theList<Folder>classes to be the type arguments RQ and RS respectively for theFunctionalService. Thus, the object of theFolderListRequestbecomes an input to thelist-foldersservice and the object ofList<Folder>type is expected as an output on completion of the service.- The plugin must extend its list-folders implementation from the
com.hcl.unica.system.integration.service.folder.list.FolderListServiceclass to be recognized as a validlist-foldersservice by the Content Integration Framework (RESTful counterpart discussed in earlier section is also a valid choice to extend from).FolderListServiceextends fromAbstractFolderListServiceclass. Details ofAbstractFolderListServiceclass are covered in the Derivatives of RestService topic.
List category folders (list-category-folders)
The specialized types used for implementing list-category-folders
are exactly same as the ones used for list-folders.
List contents (list-contents)
The following are the specialized interfaces and classes available for list-contents service:
com.hcl.unica.system.integration.service.content.list.ContentListServicePlugin can alternatively choose Functional approach to implement
list-contentsservice by extending the implementation fromContentListServiceclass. TheContentListServiceclass implements theFunctionalServiceinterface and mandates theContentListRequestand theContentPageclasses to be the type arguments RQ and RS respectively for theFunctionalService. Thus, the object of theContentListRequestbecomes an input to thelist-contentsservice and the object ofContentPagetype is expected as an output on completion of the service.- The plugin must extend its list-contents implementation from the
com.hcl.unica.system.integration.service.content.list.ContentListServiceclass to be recognized as a valid list-contents service by the Content Integration Framework (RESTful counterpart discussed in earlier section is also a valid choice to extend from).ContentListServiceextends fromAbstractContentListServiceclass. Details ofAbstractContentListServiceclass are covered in the Derivatives of RestService topic.
Get content details (get-content-details)
The following are the specialized interfaces and classes available for get-content-details service:
com.hcl.unica.system.integration.service.content.details.ContentDetailsServicePlugin can alternatively choose Functional approach to implement
get-content-detailsservice by extending the implementation fromContentDetailsServiceclass.The
ContentDetailsServiceclass implements theFunctionalServiceinterface and mandates theContentDetailsRequestand the Presentable classes to be the type arguments RQ and RS respectively for theFunctionalService. Thus, the object of theContentDetailsRequestbecomes an input to theget-content-detailsservice and the object of Presentable type is expected as an output on completion of the service.The plugin must extend its
get-content-detailsimplementation from thecom.hcl.unica.system.integration.service.content.details.ContentDetailsServiceclass to be recognized as a validget-content-detailsservice by the Content Integration Framework (RESTful counterpart discussed in earlier section is also a valid choice to extend from).ContentDetailsServiceextends fromAbstractContentDetailsServiceclass. Details ofAbstractContentDetailsServiceclass are covered in the Derivatives of RestService topic.
Get object schema (get-object-schema)
get-object-schema service is used to generate the schema of domain
object or entity used by the respective system to represent the content. Object
schema in simplest form is just a hierarchical metadata of each mappable
content/object attribute. Attribute hierarchy and metadata is expected to match the
JSON representation of the domain object. Attribute metadata mainly includes the
data type of the attribute, format of the value held in the attribute, unique
identifier of the attribute and display title or label for the attribute.
The following are the specialized interfaces and classes available for
get-object-schema service:
com.hcl.unica.system.integration.service.object.schema.ObjectSchemaProviderServiceThe
ObjectSchemaProviderServiceclass implements theFunctionalServiceinterface and mandates thecom.hcl.unica.system.model.ObjectSchemaRequestand thecom.hcl.unica.system.model.json.schema.ObjectSchemaclasses to be the type arguments RQ and RS respectively for theFunctionalService. Thus, the object of theObjectSchemaRequestbecomes an input to theget-object-schemaservice and the object ofObjectSchematype is expected as an output on completion of the service. Plugin however need not build theObjectSchemaby itself. It should just override and implement following abstract method fromObjectSchemaProviderServiceclass.ObjectProfile getObjectProfile(ObjectSchemaRequest objectSchemaRequest)
The
getObjectProfile()method acceptsObjectSchemaRequestand returnsObjectProfile. (These types are discussed in subsequent section.)The plugin must extend
get-object-schemaimplementation from thecom.hcl.unica.system.integration.service.object.schema.ObjectSchemaProviderServiceclass to be recognized as a validget-object-schemaservice by the Content Integration Framework. There is no RESTful counterpart of this standard super class since object schema generation does not include any HTTP interaction. Plugins can implement custom RESTful service and invoke it internally from withinget-object-schemaservice if required.com.hcl.unica.system.model.ObjectSchemaRequestObject of this class is supplied as an input to the
get-object-schemaservice. The most important method of this class isgetObjectIdentity()which returns an object of typecom.hcl.unica.system.model.ObjectIdentityencapsulating the details of the content chosen by the user to request the master schema. It includesapplicationId(the system identifier),objectType(content type/category identifier) andobjectId(unique identifier of the selected content).Content categorization can be strict or lenient. (Refer to
additionalFeatures | content | categorizationsection in Service declaration file for the overview of content categorization & the standard system property to declare the nature of categorization.) IfadditionalFeatures | content | categorizationis set to strict, then object schema should be generated strictly specific to the given content type/category.If categorization property is set to lenient, then regardless of the category and/or content chosen by the user at the time of setting up content mapping, the generated schema must include attributes of all kinds of contents supported by the respective system. In other words, only one master schema is used for mapping all types of contents provided by the given system.
Furthermore,
get-object-schemaservice is also used for generating schemas for request & response objects of Object extension services (known as Custom actions in Centralized Offer Management). In such case, {object-extension-service-name}.request& {object-extension-service-name}.responseare supplied inobjectTypeproperty ofObjectSchemaRequestobject.({object-extension-service-name}denotes the actual name of service declared incustom-plugin-services.ymlfile).The
getEnrichmentObjectJson()method inObjectSchemaRequestclass can be ignored as of current release.com.hcl.unica.system.integration.service.object.schema.ObjectProfileThis is a return type of
getObjectProfile()method inget-object-schemaservice. It carries the Java type corresponding to the domain entity/object representing the required type/category of content for which schema needs to be generated.. Content Integration Framework consults this Java type to generate the schema for public and non-public non static class properties (inclusive of Enums & Optionals).@MappableAttributeannotation can be used to configure each individual class property to control the schema generated by Content Integration Framework. Refer to thecom.aem.model.response.simplesearch.SimpleSearchItemdomain object inaem-integration referenceproject to get an idea about how this annotation is used. More details are provided on@MappableAttributein next section.ObjectProfilecan optionally include an instance ofcom.hcl.unica.system.integration.service.object.schema.ObjectSchemaEnricherto dynamically add/modify/remove attributes from the schema thus generated. Next section explainsObjectSchemaEnricherin detail.-
com.hcl.unica.system.integration.service.object.schema.ObjectSchemaEnricherObjectSchemaEnricheris an abstract class. Implementation ofObjectSchemaEnrichergives an opportunity to generate object schemas dynamically if the concerned domain object contains some dynamic properties (for example, dynamically added attributes to Offer Template. Each Offer Template can have different set of attributes which cannot be statically listed in corresponding Java class.). TheObjectProfileclass discussed in previous section has a property (schemaEnricher) to hold reference toObjectSchemaEnricher, if required. If dynamic enrichment is not desired, thenschemaEnricherproperty ofObjectProfilecan be left out (don���t set it to null though). Plugin should extend it to have desired implementation. The type parameter toObjectSchemaEnricherclass represents the Java type containing the additional details required for enriching the statically generated object schema. These additional details might be provided by the client applications of Unica Content Integration. As of current release, no additional details are provided, hence it should be set to Void while implementing the schema enricher.ObjectSchemaEnricherdeclares only one abstract method which should be implemented by the plugin:abstract public ObjectSchema enrich( ObjectSchema objectSchema, ObjectSchemaEnrichmentRequest<T> objectSchemaEnrichmentRequest )The first argument to this method is an instance of
com.hcl.unica.system.model.json.schema.ObjectSchemaclass. It contains the automatically generated domain object schema derived from the Java type supplied inObjectProfile. At its core,ObjectSchemais just aMap<String, AttributeSchema>, wherein class property names forms the keys of this map and property metadata ends up as an object ofAttributeSchema. If the class property in turn refers to another object, the correspondingAttributeSchemawill have anotherMap<String, AttributeSchema>containing the attributes of that object type and so on.Note: It is important to note that attribute names used as the keys in attribute map correspond to the JSON properties which ends up in the JSON representation of the domain object. Hence, if@JsonPropertyannotation is used to override the JSON property name for certain class attribute, then Content Integration Framework automatically detects it and uses the overridden property name while generating schema for the supplied Java type. Likewise,ObjectSchemaEnricherimplementation must also ensure that names of dynamically added attributes must match JSON representation of concerned domain object.ObjectSchemaas well asAttributeSchemaextend fromcom.hcl.unica.system.model.json.schema.AttributeContainerabstract class.AttributeContainerprovides convenience methods toObjectSchemaandAttributeSchemaclasses for navigating through attribute hierarchy as well as for adding, modifying and removing attributes at any level in the hierarchy to ease the schema enrichment. Attributes at any level in the hierarchy can be accessed and manipulated using their names as appearing in JSON representation. com.hcl.unica.system.model.json.schema.generator.annotations.MappableAttribute@MappableAttributeannotation provides a way to control how Content Integration Framework generates object schema from the respective Java type. Use of@MappableAttributeis not mandatory. If it is not used, Content Integration Framework automatically figures out property metadata. If required, this annotation should be placed on top of desired class properties. Following annotation attributes can be used to control the schema generation:- hidden ��� Set this to true to explicitly exclude
certain property from object schema (
@JsonIgnoreis presently not considered by Content Integration Framework. Hence, any property excluded from JSON representation using@JsonIgnoremust be explicitly excluded from schema) - id ��� Supply unique identifier for the property.
Content Integration Framework needs unique identifier for each mappable
class property. If
@MappableAttributeis not used, or id is not specified, it generates one automatically based on the location of property inside the class.Automatic generation of attribute identifier is subject to the name and the hierarchical location of class property inside the domain object graph. It implies that if the property name is changed and/or moved up or down the object graph hierarchy, it will change the identifier associated with it. Such refactoring can mislead Content Integration Framework while reading the values of refactored attributes and may lead to undesired data in mapped contents (such as Offers in COM). Hence, to avoid such inadvertent changes in attribute identifiers, we recommend you to assign unique attribute identifiers manually, which remain constant regardless of the name and location of class properties.
- title ��� Display title/label for the property. If omitted, Content Integration Framework generates one using property name.
- type ��� One of the values from
com.hcl.unica.system.model.json.schema.generator.annotations.AttributeType. If omitted, Content Integration Framework automatically figures out the appropriate type. For numeric properties holding dates as Unix timestamp (seconds since epoch), type must be set toAttributeType.INTEGER, and format must be set toAttributeFormat.DATETIME. - format ��� One of the values from
com.hcl.unica.system.model.json.schema.generator.annotations.AttributeFormat. Content Integration Framework can automatically identify standard java temporal types (Date,LocalDateTime,Instant) and set the attribute type toDATETIME. Other formats, such as URL, HTML, EMAIL should be explicitly declared. - implementation ��� Should be used for polymorphic references to explicitly declare the Java type to be considered for automatic schema generation.
- hiddenProperties -
@MappableAttributeannotation can be used at the class level to hide multiple properties at single place.hiddenPropertiestakes an array of Strings containing the names of properties (direct as well as inherited ones) to be excluded from automatically generated schema. It is particularly useful for hiding properties inherited from third party parent class. - pattern ��� Content Integration Framework supports
certain temporal types for representing date & timestamps, viz.
Date, LocalDateTime, Instant. If certain date properties are maintained in String format, then pattern can be used to declare the pattern of datestrings.typefor such attributes can be String, the format however must be set toAttributeFormat.DATETIME.patternmust contain valid pattern string supported by Java���s DateTimeFormatter. - maxItems ��� Content Integration Framework supports
schema generation & related use cases for arrays of scalers &
arrays of objects from release 12.1.2. If certain attribute is an array
or collection of scalers (primitives & their wrapper types, Strings)
or other custom Java type, then framework automatically identifies it
and sets the type of such property to
AttributeType.ARRAY. By default, framework considers maximum 1 item in the given array.maxItemscan be used to explicitly override maximum number of items such attribute can carry.maxItemsexpects and array of integers. For now, only one -dimensional arrays are supported by Content Integration Framework. Hence, the maximum items must be specified as first element of array supplied againstmaxItems. For example, maxItems = {5}. This example denotes that specified property can carry at most 5 items. It may not always carry those many items, but if it ever does, plugin doesn���t expect more than specified number items in it. ThemaxItemsvalue helps to limit the number of individual array element shown on UI at the time of Content/Object mappings. - serialization ��� By default, properties declared as
Collection<String> (List/Set) are serialized or resolved as comma
separated values (CSV). This default behavior is intact even after the
support for arrays in release 12.1.2. However, one can switch off this
default consideration for List<String> by setting serialization to
AttributeSerialization.AUTO. Thus,serializationproperty lets the developer control whether List<String> should be considered as CSV or as an array of strings. Future releases may useserializationfor controlling other aspects of attributes.
External management of attribute mappability
In addition to controlling
mappabilityof attributes by placing@MappableAttributeannotation directly on top of class properties, Content Integration Framework also allows to control each attribute externally using@MappableObjects&@MappableObjectannotations placed on top of your domain type/class. If you don���t have access to the source of your domain class or it is an auto generated class, you can create a subclass extending from it, and place@MappableObjectsannotation on top of your subclass & control each individual property inherited from parent class. Refer tocom.example.model.mapping.SubType&com.example.model.mapping.SuperTypeclasses fromasset-integration-starterproject to learn more about these annotations. If your super class uses some other nested types/classes, properties of those types can also be controlled using this approach.@MappableObjectsis an array of@MappableObject, which allows to specify the Java type & associated array of properties (@Property). The@Propertyannotation in turn carries name of the property &@MappabileAttributedeclaration for that property. All capabilities of@MappabileAttributeare available using this approach as well.- hidden ��� Set this to true to explicitly exclude
certain property from object schema (
-
Java Type to AttributeType Mapping
Following table summarizes the mapping between Java type and AttributeType/AttributeFormat used by the Content Integration Framework for automatic schema generation:
Java Type AttributeType AttributeFormat StringCharacterCharCharSequenceLocalDateLocalTimeZonedDateTimeOffsetDateTimeOffsetTimeZoneIdCalendarUUID
STRINGBooleanboolean
BOOLEANBigIntegerIntegerIntLongLongShortShortBytebyte
INTEGERBigDecimalNumberDoubleDoubleFloatfloat
NUMBERDateLocalDateTimeInstant
Content Integration Framework expects date values be expressed in UTC standard time. Temporal values expressed in any other timezone can lead to inaccurate temporal calculations in further use cases.
INTEGERDATETIMECollection<String> is resolved as comma separated list of strings. If any string element in the collection contains comma, it is enclosed in double quotes. If the enclosed string contains any double quote of its own, then its double quote is escaped by another double quote.
For example, a list of strings like [���string 1���,���string 2���,���string, 3���,���string,\���4���,���string\���5���] is resolved as follows ���
string 1,string 2,���string, 3���,���string,������4���,string���5
Notice that string���5 is not enclosed in double quotes since it does not contain any comma.
com.hcl.unica.system.model.MappableContents from content repositories are linked to Unica objects using content URLs. Once any content URL is referenced inside Unica objects, Content Integration Framework allows showing preview of already linked content by making use of
get-content-detailsservice. To achieve such content previews at later point of time, Content Integration Framework & Unica products store the system identifier, category/type & identifier of the linked content. By default, any attribute declared as AttributeType.STRING & AttributeFormat.URL using @MappableAttribute annotation will be considered as an URL belonging to the main content. If such URL attribute value is referenced in Unica objects, then the preview for such reference will show the details of content it belongs to. However, the URL attribute may not necessarily represent the content object it is wrapped in. It may be a separate entity managed inside target content repository. For example, a Book object may include two different image URL attributes, called bookCover & authorPhoto. While preview for bookCover should certainly show the details of the book it represents, authorPhoto however should show the brief bio about book���s author.With the default arrangement, Content Integration Framework continues to show the book details for authorPhoto���s preview unless explicitly overridden by the plugin. The Mappable interface provides an opportunity to override this default behavior for desired attribute. To override the content preview for any attribute, domain class must implement the Mappable interface and override following method ���
ObjectIdentity overrideObjectReference(String attributeId, ObjectIdentity defaultReference)The
overrideObjectReferencemethod accepts the attribute identifier whose real content identity needs to be established. It also receives the default identity assumed by Content Integration Framework as second argument. Plugin can conditionally override the content identity by matching theattributeIdwith desired attribute���s identifier. TheObjectIdentityreturned from this method essentially tells the real system (applicationId), category (objectType) & identifier (objectId) of the respective attribute. Returning null from this method turns the content preview off. In other circumstances, plugin should respond withdefaultReferencevalue to let the Content Integration Framework function normally.
Get cognitive analysis (get-cognitive-analysis)
The following are the specialized interfaces and classes available for get-cognitive-analysis service:
com.hcl.unica.system.integration.service.cognitive.analysis.CognitiveAnalysisServicePlugin can alternatively choose Functional approach to implement
get-cognitive-analysisservice by extending the implementation fromCognitiveAnalysisServiceclass. TheCognitiveAnalysisServiceclass implements theFunctionalServiceinterface and mandates theCognitiveAnalysisRequestand theCognitiveAnalysisclasses to be the type arguments RQ and RS respectively for theFunctionalService. Thus, the object of theCognitiveAnalysisRequestbecomes an input to theget-cognitive-analysisservice and the object ofCognitiveAnalysistype is expected as an output on completion of the service.- The plugin must extend its
get-cognitive-analysisimplementation from thecom.hcl.unica.system.integration.service.cognitive.analysis.CognitiveAnalysisServiceclass to be recognized as a validget-cognitive-analysisservice by the Content Integration Framework (RESTful counterpart discussed in earlier section is also a valid choice to extend from).CognitiveAnalysisService extends from
AbstractCognitiveAnalysisServiceclass. Details ofAbstractCognitiveAnalysisServiceclass are covered in the Derivatives of RestService topic.
Object extension service
The following are the specialized interfaces and classes available for object extension service:
com.hcl.unica.system.integration.service.object.extension.ObjectExtensionServicePlugin can alternatively choose Functional approach to implement object extension service by extending the implementation from ObjectExtensionService class. The ObjectExtensionService class implements the FunctionalService interface and mandates the ObjectExtensionRequest and the Object classes to be the type arguments RQ and RS respectively for the FunctionalService. Thus, the object of the ObjectExtensionRequest becomes an input to the object extension service and expects any type of as an output on completion of the service.
ObjectExtensionRequestis covered in more detail under RESTful section of object extension service.- The plugin must extend its object extension service implementation from the
com.hcl.unica.system.integration.service.object.extension.ObjectExtensionService
class to be recognized as a valid object extension service by the Content
Integration Framework (RESTful counterpart discussed in earlier section is also
a valid choice to extend from).
ObjectExtensionServiceextends fromAbstractObjectExtensionServiceclass. Details ofAbstractObjectExtensionServiceclass are covered in the Derivatives ofRestServicetopic.
Collaboration services
Please refer the example services from
com.example.service.functional.collaboration package in
asset-integration-starter project. Like any other Functional
counterpart of RESTful service implementation, the request & response contract
for Functional collaboration services remain same as their RESTful counterparts.
Please refer Derivatives of
RestService section for complete list of collaboration services.