Sunday, December 31, 2017

How to integrate with Salesforce.com through Salesforce Adapter in Oracle SOA Suite 12c

How to integrate with Salesforce.com through Salesforce Adapter in Oracle SOA Suite 12c

Oracle SOA Suite Salesforce adapter helps to integrate with Salesfore to perform different operation on objects like CURD, QUERY etc.
This post will explain the approach to configure Salesfore Adapter to perform different operations.

Installing Salesforce.com  SSL certificates to Weblogic server:


Download the certificates(I am using the test salesforce instance): 


Open login.salesforce.com in browser(here I am using chrome browser)
Click on certificate icon and valid

export_salesfoce_login_certificate


Click on Details and Copy to File

export_salesfoce_login_certificate


Click on Next



Saturday, December 30, 2017

JCA Binding execute of Reference operation 'search' failed due to: LDAP_ERROR_IX_INVALID_IN_REC

JCA Binding execute of Reference operation 'search' failed due to: LDAP_ERROR_IX_INVALID_IN_REC

I was getting the below exception while integrating with Ldap Adapter for search operation in Oracle SOA Suite 12c

A fault occurred while invoking the webservice operation. The fault is : <env:Fault xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<faultcode>env:Server</faultcode>
<faultstring>Exception occurred when binding was invoked.
Exception occurred during invocation of JCA binding: "JCA Binding execute of Reference operation 'search' failed due to: LDAP_ERROR_IX_INVALID_IN_REC.
Ldap Adapter has encountered an invalid operation request payload while executing an outbound interaction.
Operation request payload should be a valid instance of the ldap adapter request schema.
Please ensure that the request payload is a valid instance of the request operation schema.
".
The invoked JCA adapter raised a resource exception.
Please examine the above error message carefully to determine a resolution.
</faultstring>
<faultactor/>
<detail>
<exception>Element not completed: 'searchRequest'</exception>
</detail>
</env:Fault>
oracle.sysman.emInternalSDK.webservices.util.SoapTestException: Client received SOAP Fault from server : Exception occurred when binding was invoked.
Exception occurred during invocation of JCA binding: "JCA Binding execute of Reference operation 'search' failed due to: LDAP_ERROR_IX_INVALID_IN_REC.
Ldap Adapter has encountered an invalid operation request payload while executing an outbound interaction.
Operation request payload should be a valid instance of the ldap adapter request schema.
Please ensure that the request payload is a valid instance of the request operation schema.
".
The invoked JCA adapter raised a resource exception.
Please examine the above error message carefully to determine a resolution.

This exception occurred due to the missing input mapping for baseDN and searchFilter in the Ldap input variable(Invoke activity), make sure the variable is mapped with required input e.g. below





Configure Ldap Adapter connection factories through WLST script - Oracle SOA Suite 12c

Creating Ldap Adapter connection factories through WLST script - Oracle SOA Suite 12c

The below WLST script will help us to create the Ldap adapter connection factories in Oracle SOA Suite 12c

Change the Ldap/SOA server details accordingly in the script.

Before executing the script make sure the LdapAdapter is targeted to the SOA servers.


traget_ldap_adapter_soa_server

CreateLdapAdapterFactory.py

targetServerName='AdminServer' 

soaHome='C:\Albin\SW\SOA-12c\Oracle\Middleware\Oracle_Home\soa'

appPathLdap=soaHome+'\soa\connectors\LdapAdapter.rar'
appNameLdap='LdapAdapter'
moduleOverrideNameLdap=appNameLdap+'.rar'
LdapJNDIName = 'eis/Ldap/BlogSample'

bindDN='uid=admin,ou=system'
hostName='localhost'
password='secret'
port='10389'
trustAll='false'
trustStorePassword='false'


moduleDescriptorName='META-INF/weblogic-ra.xml'
planPathLdap='C:\Albin\workarea\Plan_Ldap.xml'

def createLdapConnectionFactory():  

edit()
startEdit()
startApplication(appNameLdap)
myPlanLdap=loadApplication(appPathLdap, planPathLdap)
makeDeploymentPlanVariable(myPlanLdap,'ConnectionInstance_eis/Ldap_JNDIName_13102979357209', LdapJNDIName , '/weblogic-connector/outbound-resource-adapter/connection-definition-group/[connection-factory-interface="javax.resource.cci.ConnectionFactory"]/connection-instance/[jndi-name="'+LdapJNDIName+'"]/jndi-name',moduleOverrideNameLdap)
makeDeploymentPlanVariable(myPlanLdap, 'ConfigProperty_eis/Ldap_JNDIName_Host_Name_13102979357210', bindDN,'/weblogic-connector/outbound-resource-adapter/connection-definition-group/[connection-factory-interface="javax.resource.cci.ConnectionFactory"]/connection-instance/[jndi-name="'+LdapJNDIName+'"]/connection-properties/properties/property/[name="bindDN"]/value',moduleOverrideNameLdap)
makeDeploymentPlanVariable(myPlanLdap, 'ConfigProperty_eis/Ldap_JNDIName_Port_13102979357211', hostName,'/weblogic-connector/outbound-resource-adapter/connection-definition-group/[connection-factory-interface="javax.resource.cci.ConnectionFactory"]/connection-instance/[jndi-name="'+LdapJNDIName+'"]/connection-properties/properties/property/[name="hostName"]/value',moduleOverrideNameLdap)
makeDeploymentPlanVariable(myPlanLdap, 'ConfigProperty_eis/Ldap_JNDIName_Port_13102979357212', password,'/weblogic-connector/outbound-resource-adapter/connection-definition-group/[connection-factory-interface="javax.resource.cci.ConnectionFactory"]/connection-instance/[jndi-name="'+LdapJNDIName+'"]/connection-properties/properties/property/[name="password"]/value',moduleOverrideNameLdap)
makeDeploymentPlanVariable(myPlanLdap, 'ConfigProperty_eis/Ldap_JNDIName_Port_13102979357213', port,'/weblogic-connector/outbound-resource-adapter/connection-definition-group/[connection-factory-interface="javax.resource.cci.ConnectionFactory"]/connection-instance/[jndi-name="'+LdapJNDIName+'"]/connection-properties/properties/property/[name="port"]/value',moduleOverrideNameLdap)
makeDeploymentPlanVariable(myPlanLdap, 'ConfigProperty_eis/Ldap_JNDIName_Port_13102979357214', trustAll,'/weblogic-connector/outbound-resource-adapter/connection-definition-group/[connection-factory-interface="javax.resource.cci.ConnectionFactory"]/connection-instance/[jndi-name="'+LdapJNDIName+'"]/connection-properties/properties/property/[name="trustAll"]/value',moduleOverrideNameLdap)
makeDeploymentPlanVariable(myPlanLdap, 'ConfigProperty_eis/Ldap_JNDIName_Port_13102979357215', trustStorePassword,'/weblogic-connector/outbound-resource-adapter/connection-definition-group/[connection-factory-interface="javax.resource.cci.ConnectionFactory"]/connection-instance/[jndi-name="'+LdapJNDIName+'"]/connection-properties/properties/property/[name="trustStorePassword"]/value',moduleOverrideNameLdap)


myPlanLdap.save();
save();
cd('/AppDeployments/LdapAdapter/Targets');
updateApplication(appNameLdap, planPathLdap);
startApplication(appNameLdap);
activate(block='true');

    
def makeDeploymentPlanVariable(wlstPlan, name, value, xpath,overrideName, origin='planbased'):
    wlstPlan.destroyVariable(name)
    wlstPlan.destroyVariableAssignment(name, overrideName, moduleDescriptorName)
    variableAssignment = wlstPlan.createVariableAssignment(name, overrideName, moduleDescriptorName)
    variableAssignment.setXpath(xpath)
    variableAssignment.setOrigin(origin)
    wlstPlan.createVariable(name, value)
    print 'moduleDescriptorName=',moduleDescriptorName


def main():
       #SOA Server Details
       adminURL='t3://localhost:7201'
       adminUserName='weblogic'
       adminPassword='Albin123!'
       connect(adminUserName, adminPassword, adminURL)
       createLdapConnectionFactory()
       disconnect()
main()



Creating Coherence Adapter connection factories through WLST script - Oracle SOA Suite 12c

Creating Coherence Adapter connection factories through WLST script - Oracle SOA Suite 12c

The below WLST script will help us to create the Coherence adapter connection factories in Oracle SOA Suite 12c

Change the Coherence/SOA server details accordingly in the script.

Before executing the script make sure the CoherenceAdapter is targeted to the SOA servers.


traget_coherence_adapter_soa_server

CreateCoherenceAdapterFactory.py

targetServerName='AdminServer' 

soaHome='C:\Albin\SW\SOA-12c\Oracle\Middleware\Oracle_Home\soa'

appPathCoherence=soaHome+'\soa\connectors\CoherenceAdapter.rar'
appNameCoherence='CoherenceAdapter'
moduleOverrideNameCoherence=appNameCoherence+'.rar'
CoherenceJNDIName = 'eis/Coherence/BlogSample'

CacheConfigLocation='C:\Albin\workarea\coherence-adapter-config.xml'
ClassLoaderMode='CUSTOM'
WLSExtendProxy='false'
PojoJarFile='C:\Albin\workarea\cache-pojos.jar' # Include this if Cache Type is POJO - Jar file contains the POJO classes
ServiceName='DistributedCache' #ServiceName configured in Cache Config File.

moduleDescriptorName='META-INF/weblogic-ra.xml'
planPathCoherence='C:\Albin\workarea\Plan_Coherence.xml'

def createCoherenceConnectionFactory():  

edit()
startEdit()
startApplication(appNameCoherence)
myPlanCoherence=loadApplication(appPathCoherence, planPathCoherence)
makeDeploymentPlanVariable(myPlanCoherence,'ConnectionInstance_eis/Coherence_JNDIName_13102979357209', CoherenceJNDIName , '/weblogic-connector/outbound-resource-adapter/connection-definition-group/[connection-factory-interface="javax.resource.cci.ConnectionFactory"]/connection-instance/[jndi-name="'+CoherenceJNDIName+'"]/jndi-name',moduleOverrideNameCoherence)
makeDeploymentPlanVariable(myPlanCoherence, 'ConfigProperty_eis/Coherence_JNDIName_Host_Name_13102979357210', CacheConfigLocation,'/weblogic-connector/outbound-resource-adapter/connection-definition-group/[connection-factory-interface="javax.resource.cci.ConnectionFactory"]/connection-instance/[jndi-name="'+CoherenceJNDIName+'"]/connection-properties/properties/property/[name="CacheConfigLocation"]/value',moduleOverrideNameCoherence)
makeDeploymentPlanVariable(myPlanCoherence, 'ConfigProperty_eis/Coherence_JNDIName_Port_13102979357211', ClassLoaderMode,'/weblogic-connector/outbound-resource-adapter/connection-definition-group/[connection-factory-interface="javax.resource.cci.ConnectionFactory"]/connection-instance/[jndi-name="'+CoherenceJNDIName+'"]/connection-properties/properties/property/[name="ClassLoaderMode"]/value',moduleOverrideNameCoherence)
makeDeploymentPlanVariable(myPlanCoherence, 'ConfigProperty_eis/Coherence_JNDIName_Port_13102979357212', WLSExtendProxy,'/weblogic-connector/outbound-resource-adapter/connection-definition-group/[connection-factory-interface="javax.resource.cci.ConnectionFactory"]/connection-instance/[jndi-name="'+CoherenceJNDIName+'"]/connection-properties/properties/property/[name="WLSExtendProxy"]/value',moduleOverrideNameCoherence)
makeDeploymentPlanVariable(myPlanCoherence, 'ConfigProperty_eis/Coherence_JNDIName_Port_13102979357213', PojoJarFile,'/weblogic-connector/outbound-resource-adapter/connection-definition-group/[connection-factory-interface="javax.resource.cci.ConnectionFactory"]/connection-instance/[jndi-name="'+CoherenceJNDIName+'"]/connection-properties/properties/property/[name="PojoJarFile"]/value',moduleOverrideNameCoherence)
makeDeploymentPlanVariable(myPlanCoherence, 'ConfigProperty_eis/Coherence_JNDIName_Port_13102979357214', ServiceName,'/weblogic-connector/outbound-resource-adapter/connection-definition-group/[connection-factory-interface="javax.resource.cci.ConnectionFactory"]/connection-instance/[jndi-name="'+CoherenceJNDIName+'"]/connection-properties/properties/property/[name="ServiceName"]/value',moduleOverrideNameCoherence)

myPlanCoherence.save();
save();
cd('/AppDeployments/CoherenceAdapter/Targets');
updateApplication(appNameCoherence, planPathCoherence);
startApplication(appNameCoherence);
activate(block='true');

    
def makeDeploymentPlanVariable(wlstPlan, name, value, xpath,overrideName, origin='planbased'):
    wlstPlan.destroyVariable(name)
    wlstPlan.destroyVariableAssignment(name, overrideName, moduleDescriptorName)
    variableAssignment = wlstPlan.createVariableAssignment(name, overrideName, moduleDescriptorName)
    variableAssignment.setXpath(xpath)
    variableAssignment.setOrigin(origin)
    wlstPlan.createVariable(name, value)
    print 'moduleDescriptorName=',moduleDescriptorName


def main():
       #SOA Server Details
       adminURL='t3://localhost:7201'
       adminUserName='weblogic'
       adminPassword='Albin123!'
       connect(adminUserName, adminPassword, adminURL)
       createCoherenceConnectionFactory()
       disconnect()

main()


Friday, December 29, 2017

Create Java DB connection in JDeveloper 12.2.1.3.0

Click on Windows - Database - Databases

Jdeveloper_Java_DB_connection
Create new IDE connection

Jdeveloper_Java_DB_connection

Select the Connection Type as Java DB/Apache Derby
Username -  soainftra
Driver Class - org.apache.derby.jdbc.ClientDriver
HostName - localhost (or enter the IP address)
JDBC Port -  1527
Database Name - soinfra
Password - Leave blank

Click on Test Connection - the result will display as success

The tables can  be accessed now - Open the SQL Worksheet and execute the required SQL queries

e.g - select * from soainfra.cube_instance

Jdeveloper_Java_DB_connection



ORABPEL-05215 error while deploying Oracle SOA Suite 12c composites

I was receiving the following exception while deploying the Oracle SOA Suite 12c composite from JDeveloper.

 [04:43:18 PM] Error deploying archive sca_Project1.jar to partition "default" on server AdminServer [http://DESKTOP-7UQNDE3:7201]
[04:43:18 PM] HTTP error code returned [500]
[04:43:18 PM] Error message from server:
There was an error deploying the composite on AdminServer: Error occurred during deployment of component: BPELProcess1 to service engine: implementation.bpel, for composite: Project1: ORABPEL-05215

Error while loading process.
The process domain is encountering the following errors while loading the process "BPELProcess1" (composite "default/Project1!1.0*soa_4c17e942-2799-4e2a-b152-bf969c7308ab"): null.
This error contained an exception thrown by the underlying process loader module.
Check the exception trace in the log (with logging level set to debug mode). If there is a patch installed on the server, verify that the bpelcClasspath domain property includes the patch classes.
.

[04:43:18 PM] Check server log for more details.
[04:43:18 PM] Error deploying archive sca_Project1.jar to partition "default" on server AdminServer [http://DESKTOP-7UQNDE3:7201]
[04:43:18 PM] Deployment cancelled.
[04:43:18 PM] ----  Deployment incomplete  ----.
[04:43:18 PM] Error deploying archive file:/C:/Albin/SW/SOA-12c/Workspace/deploy/sca_Project1.jar
 (oracle.tip.tools.ide.fabric.deploy.common.SOARemoteDeployer)


ORABPEL-05215 will be thrown if there is any compilation error in the component while deploying to the server.

In my case, i have added a empty Java Embedding activity with out adding any java code into that.

The component successfully deployed after removing the Java Embedding activity or adding some sample java code into it.


Restrict the access to SOA Composite Service based on the User Role (Authorization to the SOA Composite Service) – Oracle SOA Suite 12c

Restrict the access to SOA Composite Service based on the User Role (Authorization to the SOA Composite Service) – Oracle SOA Suite 12c

Sometimes we may need to restrict the access to the SOA composite service based on the user role.
HTTP basic authentication and an authorization policy can be used to ensure that access is only granted to users who are members of a particular role.

This blog will explain the steps to enable authorization to our composite service.

Configure the Users and Group:

  • Login to the Weblogic console ('http://<host>:<port>/console')
  • In the left menu select 'Security Realms'
  • Select the realm where you want to create the users and groups.  The default is 'myrealm'
  • At the top select the 'Users and Groups' tab
  • Select User tab and Click 'New' and enter your user name and pwd.  Here am creating the user albin and albin1, create as many users as you want
  • Select ‘Groups’ tab and create a new group.  Here I am creating  ‘IntegrationGroup’
  • Go back to the users and click on  'Albin'
  • Select the 'Groups' tab and add ‘IntegrationGroup’.  The user albin1 will not be part of this group.

Configure the Application Role:

  • Login to EM console
  • Click on Target Navigation - WebLogic Domain - Domain Name 
  • Click on Weblogic Domain - Select Security and Click on Application Roles
soa-infra_application_roles
  • Select Application Stripe as soa-infra
  • Click on 'Create' to configure a new Application Role


Friday, December 22, 2017

Approach to 301 redirect the internal URL's to dynamic SEO friendly URL - Adobe Experience Manager

Approach to 301 redirect the internal URL's to dynamic SEO friendly URL - Adobe Experience Manager

This post will explain the approach to 301 redirect the internal URL's to dynamic SEO friendly URL.

We had a scenario to display the SEO friendly URL to the user instead of displaying the internal URL for the PDP pages in eCommerce website - The SEO friendly URL is formed dynamically based on the product title and format from Hybris.

The internal product URL is - /en/test/pdp/book.html?id=123(Internal Publisher page that handle the request based on the product id)
New SEO friendly URL - /en/test/Sample_Book/book/pdp.html?id=123(Dynamic URL and should be rewritten to internal URL to process by publisher )

When ever user access the SEO specific URL(/en/test/Sample_Book/book/pdp.html?id=123) in the browser the user should be redirected to internal URL(/en/test/pdp/book.html?id=123) without changing the Browser URL.

Also, the user should be 301 redirected to SEO friendly URL while accessing the internal URL directly from the browser.

Redirect the internal URL to new Dynamic URL:


As the new URL is dynamic based on the product title and product format` from Hybris, the dispatcher rules cant be defined to handle the redirect from internal URL to new SEO friendly dynamic URL.

The alternative solution is define a Request filter that will form the dynamic URL by fetching the product tile from Hybris and 301 redirect to new URL.

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

import org.apache.felix.scr.annotations.sling.SlingFilter;
import org.apache.felix.scr.annotations.sling.SlingFilterScope;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;

@SlingFilter(label = "301 URL redirector", description = "301 URL redirector", metatype = true, generateComponent = true, // True if you want to leverage activate/deactivate
generateService = true, order = 0, scope = SlingFilterScope.REQUEST)
public class Redirect301HandlerFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {

final SlingHttpServletRequest slingRequest = (SlingHttpServletRequest) request;
final SlingHttpServletResponse slingResponse = (SlingHttpServletResponse) response;
String requestPath= slingRequest.getRequestURI();
String pid = slingRequest.getParameter("pid");
if (!requestPath.contains("/pdp/") || slingRequest.getParameter("isInternalRedirect")!=null) {
chain.doFilter(request, response);
return;
}

String title = "";// Get the product tile and product format from Hybris based on the pid
String format = "";//// Get the product tile and product format from Hybris based on the pid

String newURL = slingRequest.getScheme() + "://" + slingRequest.getServerName() + ":"+ slingRequest.getServerPort() + "/en/test/" + title + "/" + format + "/pdp.html?pid=" + pid;

slingResponse.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
slingResponse.setHeader("Location", newURL);
}

@Override
public void destroy() {
// TODO Auto-generated method stub
}
}

Rewrite the SEO friendly URL to internal URL:


The SEO friendly URL is not recognized by publisher so rewrite the SEO friendly URL to internal URL in dispatcher without changing browser URL.The below post provides the steps to rewrite the URL to internal URL without changing the browser URL.

https://www.albinsblog.com/2017/11/rewrite-rules-with-ptpass-through-flag-notwork-in-aem.html

Add a additional parameter isInternalRedirect while rewriting the SEO URL to internal URL from Dispatcher to avoid the redirect loop

RewriteCond %{QUERY_STRING} ^id=(.*) [NC]
RewriteRule ^/en/test/(.*)/(.*)/pdp.html$ /en/test/pdp/$2.html?isInternalRedirect=true&id=%1 [PT,L]


Monday, December 18, 2017

How to get the Inherited Properties in Adobe Experience Manager Servlet's or Filter's

How to get the Inherited Properties in Adobe Experience Manager Servlet's or Filter's

This post will explain the approach to get the inherited properties in AEM servlet's or Filter's.

Sample Filter - Retrieves the inherited page properties and component properties:


HierarchyNodeInheritanceValueMap - This will help to retrieve the inherited properties from parent pages.

While accessing the property prop1 from /content/site/en/test/jcr:content - /content/site/en/test/jcr:content/@prop1,the system searches in the following paths

/content/site/en/test/jcr:content/@prop1
/content/site/en/jcr:content/@prop1
/content/site/jcr:content/@prop1

If the prop1 is located in any of the above paths then the corresponding values is returned, if not it will return null value.

ComponentInheritanceValueMap - This will help to retrieve the inherited properties from parent components.

While accessing the prop2 property from /content/site/en/test/jcr:content/T01_region4/titletext_e8d0 - /content/site/en/test/jcr:content/T01_region4/titletext_e8d0/@prop2,the system searches in the following paths

/content/site/en/test/jcr:content/T01_region4/titletext_e8d0/@prop2
/content/site/en/test/jcr:content/T01_region4/@prop2
/content/site/en/test/jcr:content/@prop2

If the prop2 is located in any of the above paths then the corresponding values is returned, if not it will return null value.

import java.io.IOException;

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;

import org.apache.felix.scr.annotations.*;
import org.apache.felix.scr.annotations.sling.SlingFilter;
import org.apache.felix.scr.annotations.sling.SlingFilterScope;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;

import com.day.cq.commons.inherit.ComponentInheritanceValueMap;
import com.day.cq.commons.inherit.HierarchyNodeInheritanceValueMap;
import com.day.cq.commons.inherit.InheritanceValueMap;

@SlingFilter(label = "301 URL redirector", description = "301 URL redirector", metatype = true, generateComponent = true,
generateService = true, order = 0, scope = SlingFilterScope.REQUEST)
public class Redirect301HandlerFilter implements Filter {

@Override
public void init(FilterConfig filterConfig) throws ServletException {

}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

final SlingHttpServletRequest slingRequest = (SlingHttpServletRequest) request;
final SlingHttpServletResponse slingResponse = (SlingHttpServletResponse) response;
String resourcePathURL = slingRequest.getResource().getPath();

ResourceResolver resourceResolver = slingRequest.getResourceResolver();
String resourceContentPath = resourcePathURL.split(".html")[0] + "/jcr:content";
Resource res = resourceResolver.getResource(resourceContentPath);

InheritanceValueMap inheritedProp = new HierarchyNodeInheritanceValueMap(res);
String prop1 = inheritedProp.getInherited("prop1", String.class);

res = resourceResolver.getResource(resourceContentPath+"/T01_region4/titletext_e8d0");

InheritanceValueMap inheritedPropCom = new ComponentInheritanceValueMap(res);
String prop2 = inheritedPropCom.getInherited("prop2", String.class);

chain.doFilter(slingRequest, slingResponse);

}

@Override
public void destroy() {
// TODO Auto-generated method stub

}

}



Thursday, December 14, 2017

com.day.cq.searchpromote.Search ParseError at [row,col]:[1,1] Message: Content is not allowed in prolog - Adobe Search and Promote

com.day.cq.searchpromote.Search ParseError at [row,col]:[1,1] Message: Content is not allowed in prolog - Adobe Search and Promote

I was getting the below exception while searching the documents from Search&Promote in Adobe Experience Manager website.

14.12.2017 17:49:43.040 *ERROR* [10.204.139.58 [1513273782091] GET /content/test/en/search.html HTTP/1.1] com.day.cq.searchpromote.Search ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.
javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.
        at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:596)
        at com.sun.xml.internal.stream.XMLEventReaderImpl.nextEvent(XMLEventReaderImpl.java:83)
        at com.day.cq.searchpromote.xml.result.ResultParser.getNextEvent(ResultParser.java:61)
        at com.day.cq.searchpromote.xml.result.ResultParser.parse(ResultParser.java:48)
        at com.day.cq.searchpromote.Search.parseResults(Search.java:526)
        at com.day.cq.searchpromote.Search.<init>(Search.java:154)
        at com.tr.openweb.ecommerce.sly.search.SearchInitializer.activate(SearchInitializer.java:69)
        at com.tr.openweb.ecommerce.sly.search.SearchBarPage.activate(SearchBarPage.java:19)
        at com.adobe.cq.sightly.WCMUsePojo.init(WCMUsePojo.java:84)
        at org.apache.sling.scripting.sightly.impl.engine.extension.use.JavaUseProvider.provide(JavaUseProvider.java:119)
        at org.apache.sling.scripting.sightly.impl.engine.extension.use.UseRuntimeExtension.call(UseRuntimeExtension.java:84)
        at org.apache.sling.scripting.sightly.impl.engine.runtime.RenderContextImpl.call(RenderContextImpl.java:66)
        at org.apache.sling.scripting.sightly.apps.test.components.search.searchBarPage.SightlyJava_searchBarPage.render(SightlyJava_searchBarPage.java:44

I was not able to identify any configuration issues with AEM  or Search&Promote.

It looks to be the issue was caused due to the renaming of existing Search-Promote cloud configuration in AEM, the renaming of the configuration created some internal issue and due that the search was failing with parsing error, the issue got resolved after deleting and recreating the Search-Promote cloud configuration.


IndexConnector prefetch failed - Adobe Search and Promote

IndexConnector prefetch failed - Adobe Search and Promote 

Index Connector can be used to define additional input sources for indexing XML pages or any kind of feed.

The  Index Connector is not enabled in the Search and Promote account by default, the  Index Connector can be only enabled by reaching out to Search and Promote consultant or support team.

Search_and_promote_index_connector

After enabling the Index Connector the regular indexing stopped working with the following exception.

1: 12/14 13:10:14 CST ======== Starting manual crawl of account spxxxxxx. ========
2: 12/14 13:10:14 CST ERROR: IndexConnector prefetch failed.
3: 12/14 13:10:15 CST Starting update of slice list.
4: 12/14 13:10:15 CST Skipping update of slice list - no change since last update.
5: 12/14 13:10:15 CST Refreshing auto-complete word list.
6: 12/14 13:10:15 CST Finished refreshing auto-complete word list.
7: 12/14 13:10:15 CST Creating GS config.
8: 12/14 13:10:15 CST Finished creating GS config.
9: 12/14 13:10:15 CST --------------------------------------------------------------------
10: 12/14 13:10:15 CST *** Crawl Summary ***
11: 12/14 13:10:15 CST Start Time: 12/14/2017 13:10:14 CST
12: 12/14 13:10:15 CST End Time: 12/14/2017 13:10:15 CST
13: 12/14 13:10:15 CST Elapsed Time: 1 second
14: 12/14 13:10:15 CST Pages Crawled: 0 pages
15: 12/14 13:10:15 CST Words/Bytes Indexed: 0 words/ 0 bytes
16: 12/14 13:10:15 CST Depth: 1
17: 12/14 13:10:15 CST Errors: 1
18: 12/14 13:10:15 CST Starting update of slice list.
19: 12/14 13:10:15 CST Skipping update of slice list - no change since last update.
20: 12/14 13:10:15 CST *** Index Summary ***
21: 12/14 13:10:15 CST Total Pages: 278
22: 12/14 13:10:15 CST --------------------------------------------------------------------
23: 12/14 13:10:15 CST ======== Finish manual crawl of account spxxxxx: Aborted. ========

This will be fixed after enabling at least one Index Connector configuration, if the actual Index Connector Configuration can't be created then create a dummy configuration with disabled status that will fix the indexing issue.
S&P_index_connector_configuration

S&P_index_connector_configuration



Monday, December 11, 2017

Different approaches to integrate Adobe Experience Manager(AEM) with Eloqua

Different approaches to integrate Adobe Experience Manager(AEM) with Eloqua


This post will explain the different approaches to integrate Adobe Experience Manager(AEM) with Eloqua to capture the user data.

Eloqua Landing Page:


Define a Landing page in Eloqua with requred form fields and action, redirect the user to the Landing page from AEM whenever required to capture the data.User data will be directly submitted to the Eloqua without any interaction from AEM.

In this approach while defining the Landing page in Eloqua the look and feel of the landing page should be matched with AEM pages look and feel for better user experience.

Refer the following URL to more details on defining a landing page -
https://docs.oracle.com/cloud/latest/marketingcs_gs/OMCAA/Help/LandingPages/Tasks/CreatingNewLandingPagesDesignEditor.htm

Submit the data through Eloqua form - Directly to Eloqua Form Action URL:


Define the form in Eloqua with required fields, place the form in a AEM component- change the look and feel accordingly.

Eloqua_form_creation
Select Basic Form option
Eloqua_form_options
Define required fields in the form
Eloqua_form_fields



Saturday, December 9, 2017

How to display the Google Adsense at the bottom of the page in mobile view?

How to display the Google Adsense at the bottom of the page in mobile view?

Sometimes we may required to display the specific ad only in the mobile view at the bottom of the page. This post will explain the approach to display the adsense ads at the bottom of the page in mobile view.

google_adsense_mobile_bottom

 Enable Custom template for Mobile view: 

 Make sure the custom template for the mobile view is selected

mobile_custom_template

 Enable adsense at the bottom of the page in mobile view: 

 Add a HTML/JavaScript widget at the bottom of side bar

widget-sidebar-bottom

 Add the google adsense script in the widget
 Identify the the widget id of the new widget added

widget-configuration


 Save the widget and the Layout arrangement

 Go to Blogger Dashboard > Theme > EDIT HTML

Locate widget with the widget id and add mobile='only' configuration as shown below - this will make sure this widget will be displayed only in mobile view

  <b:widget id='HTML6' locked='false' mobile='only' title='' type='HTML'>
 
mobile-only-widget
 
  Save Theme
 
  This will display the add at the bottom of the blogger mobile view.
  You can how test if the Google Adsense is displaying at the bottom of the blogger mobile view


How to display the Google Adsense between blogger posts in mobile home page view?

How to display the Google Adsense between blogger posts in mobile home page view?

 This post will explain the approach to display the adsense ads between posts in mobile home page view.

adsense_between_posts_mobile_home

 Enable Custom template for Mobile view:

 Make sure the custom template for the mobile view is selected

mobile_custom_template

 Add adsense between posts in mobile home view: 

Go to Blogger Dashboard > Theme > EDIT HTML

 Locate <b:include data='post' name='mobile-index-post'/>

 Replace

 <b:loop values='data:posts' var='post'>
    <b:include data='post' name='mobile-index-post'/>
 </b:loop>
 
  With
 
  <b:loop index='x' values='data:posts' var='post'>
    <b:include data='post' name='mobile-index-post'/>
  <b:if cond='(data:x+1)%2==0'>  
  <!-- Add adsense code here -->  
</b:if>
  </b:loop>
 
  Save Theme
 
  This will display the add after every two posts in the blogger mobile home view - Change the condition based on your requirement
 
  You can how test if the Google Adsense is displaying between the posts in mobile home view.


Thursday, November 30, 2017

Flush the dispatcher cache for DAM assets used on multiple websites(Domains) through ACS AEM Commons - Dispatcher Flush Rules

Flush the dispatcher cache for dam assets used on multiple websites through ACS AEM Commons - Dispatcher Flush Rules

Some cases, the same DAM asset is used on multiple websites(Domains) and the individual websites caches the assets locally, the regular replication agent configuration will not clear the cache for all the websites that use the common DAM asset.

This post will explain the approach to flush the dispatcher cache for common DAM assets used om multiple websites through ACS AEM Commons - Dispatcher Flush Rules - Adobe Experience Manager(AEM).

Install acs-aem-commons-content-3.9.0.zip package(ignore if it is already available):


ACS commons package download link:
https://github.com/Adobe-Consulting-Services/acs-aem-commons/releases/tag/acs-aem-commons-3.9.0
 

Configure the ResourceOnly Flush agent in publisher:


Create the Flush agent in publisher with following configuration


Dispatcher DAM Flush Agent



Friday, November 24, 2017

Rewrite Rules with PT(Pass Through) Flag is not working in AEM Dispatchers - Adobe Experience Manager(AEM)

Rewrite Rules with PT(Pass Through) Flag is not working in AEM Dispatchers - Adobe Experience Manager(AEM)

How to define SEO/User friendly URL's in Adobe Experience Manager(AEM)


The Rewrite Rules with PT Flag helps us to define the SEO/User friendly URL's by hiding the internal URL's.

Let consider a scenario - The product URL should be rewritten to SEO/User friendly URL.

The internal product URL is - /en/test/pdp/book.html?id=123, this URL is not SEO/User friendly as the title of the the product is not part of the URL

The URL should be rewritten to /en/test/Sample_Book/book/pdp.html?id=123 internally without changing the Browser URL

Rewrite_Rule_with_PT_flag



Sunday, November 5, 2017

ORABPEL-05250 Error - JDeveloper Part2

ORABPEL-05250 Error - JDeveloper Part2

I was facing a strange issue while deploying the composite to the server but The composite was successfully build in JDeveloper but during deployment to the server received the following exception.

[02:02:37 PM] Sending archive - sca_SuppressSelectionFailure_rev1.0.jar
[02:02:49 PM] Received HTTP response from the server, response code=500
[02:02:49 PM] Error deploying archive sca_SuppressSelectionFailure_rev1.0.jar to partition "default" on server AdminServer [http://inkaban3ua-eai05:8000]
[02:02:49 PM] HTTP error code returned [500]
[02:02:49 PM] Error message from server:
There was an error deploying the composite on AdminServer: Error occurred during deployment of component: SuppressSelectionFailure to service engine: implementation.bpel, for composite: SuppressSelectionFailure: ORABPEL-05250

Error deploying BPEL suitcase.
error while attempting to deploy the BPEL component file "/fmw/config/admin/domains/SOACoreDomain/servers/AdminServer/dc/soa_1b6f358e-8947-4572-a573-e036770c0591"; the exception reported is: java.lang.Exception: BPEL 1.1 compilation failed

This error contained an exception thrown by the underlying deployment module.
Verify the exception trace in the log (with logging level set to debug mode).
.

[02:02:49 PM] Check server log for more details.
[02:02:49 PM] Error deploying archive sca_SuppressSelectionFailure_rev1.0.jar to partition "default" on server AdminServer [http://localhost:8000]
[02:02:49 PM] ####  Deployment incomplete.  ####
[02:02:49 PM] Error deploying archive file:/C:/JDeveloper/mywork/Application1/SuppressSelectionFailure/deploy/sca_SuppressSelectionFailure_rev1.0.jar
 (oracle.tip.tools.ide.fabric.deploy.common.SOARemoteDeployer)


java.lang.ClassCastException for the same class com.sample.test.Test cannot be cast to com.sample.test.Test - Adobe Experience Manager(AEM)

java.lang.ClassCastException for the same class com.sample.test.Test cannot be cast to com.sample.test.Test - Adobe Experience Manager(AEM)

We were facing a strange ClassCastException - ClassCastException pointing to the same class in Adobe Experience Manager(AEM)

java.lang.ClassCastException: com.sample.test.Test cannot be cast to com.sample.test.Test

While analyzing through depfinder - http://localhost:4502/system/console/depfinder, there is two version of the same class available from two different packages.

But this class is only defined in one of the package and referred in the other package, after analyzing the Sling class loading is little different - If one of the class com.sample.test.Test is referred from different package, Sling copies the classes locally to the target package and if the target package export the same package(<Export-Package>) -  com.sample.* then Sling export the classes copied from other package that matches the export pattern, in this case our target package is already exporting com.sample.* so two version of same class is available now. This will lead to the ClassCastException specified above.

To fix this issue, we can change the target package pom.xml file to restrict the export of referred classes from other package.

<Export-Package>com.sample.*,!com.sample.test</Export-Package>

Please make sure the restricted package - !com.sample.test is kept after the wider package - com.sample.*

Now only one version of the class from source package is available for reference.


Wednesday, July 5, 2017

Exposing the AEM resources through OAuth - Adobe Experience Manager(AEM)

Exposing the AEM resources through OAuth - Adobe Experience Manager(AEM)

This post will explain the approach to expose the resources through OAuth in Adobe Experience Manager(AEM).

Refer https://www.albinsblog.com/2017/05/how-to-get-basic-profile-details-of-user-through-oauth.html for the basic configurations to expose the the resources thorough OAuth.

Exposing /etc/designs/geometrixx/static.css through OAuth

Configure the "Allowed Scope" as "/etc/designs/geometrixx"(based on the resource that should be exposed) in "Adobe Granite OAuth Resource Server"


The OAuth Authentication handler is not enabled by default and it looks to be an product defect.




Monday, May 29, 2017

How to expose Regex based rest service in Adobe Experience Manager( AEM)

How to expose Regex based rest service in Adobe Experience Manager(AEM)

This post will explain the approach to expose the regex based rest service in Adobe Experience Manager(AEM). By default OSGI will not support exposing regex based rest services and it will only support the services based on the specified Path or Resource Type.

Install OSGI JAX-RS connector:

Install(/system/console/bundles) jersey-all, publisher, provider-security and other required bundles e.g. provider-gson for JSON support and make sure the bundles are in Active state.

The bundles(jar) can be downloaded from following URL - http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.eclipsesource.jaxrs%22

com.eclipsesource.jaxrs-bundles

Develop the Servlet with required path mapping:

>=AEM 6.2

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

import org.osgi.service.component.annotations.Component;

@Component(service = RegexServlet.class)
@Path("/{catagroy}/{title}/p/{code : \\d{5}}")
public class RegexServlet {

  @GET
  @Produces({MediaType.TEXT_PLAIN})
  public String getProductDetails(@Context HttpServletRequest request, @Context HttpServletResponse response,@PathParam("catagroy") String catagroy,@PathParam("title") String title,@PathParam("code") String code) {

    return "code="+code+";catagroy="+catagroy+";title="+title;

    }
}

< AEM 6.2

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import javax.ws.rs.Path;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Service(RegexServlet.class)
@Component(metatype = false)
@Path("/{catagroy}/{title}/p/{code : \\d{5}}")
public class RegexServlet {

 @GET
 @Produces({MediaType.TEXT_PLAIN})
public String getProductDetails(@Context HttpServletRequest request, @Context HttpServletResponse response,@PathParam("catagroy") String catagroy,@PathParam("title") String title,@PathParam("code") String code) {

   return "code="+code+";catagroy="+catagroy+";title="+title;

    }
}

Add the following dependency in POM.xml

<dependency>
    <groupId>javax.ws.rs</groupId>
    <artifactId>javax.ws.rs-api</artifactId>
    <version>2.0</version>
</dependency>

Install the package and make sure the core bundle status is active.

Verify whether the RegexServlet service is registered in system console

JAX-RS_Servlet

The servlet will accept the request with matching pattern - the servlet path should be starting with /services

The Path Regex pattern specified in the servlet will match for the following URL  - localhost:4502/services/categoryTest/Sampletitle/p/12345 (Code should be 5 digit)

Download the sample code -https://gitlab.com/albinsblog-data/RegexServlet/tree/master (Refer com.regex.servlet.core.RegexServlet.java in core module)
The sample code is tested in AEM 6.3 but it should be working in 6.2