Akshay Sura - Partner
26 Aug 2018
In this video, I am going to walk you through how to use xConnect in a Sitecore Commerce Engine solution.
We will:
Useful links:
If you have any questions or concerns, please get in touch with me. (@akshaysura13 on twitter or on Slack).
using
System
;
using
System
.
Collections
.
Generic
;
using
System
.
Linq
;
using
System
.
Threading
.
Tasks
;
using
Konabos
.
XConnect
.
Loyalty
.
Model
.
Facets
;
using
Konabos
.
XConnect
.
Loyalty
.
Model
.
Models
;
using
Sitecore
.
Commerce
.
Core
;
using
Sitecore
.
Commerce
.
Plugin
.
Customers
;
using
Sitecore
.
XConnect
;
using
Sitecore
.
XConnect
.
Client
;
using
Sitecore
.
XConnect
.
Client
.
WebApi
;
using
Sitecore
.
XConnect
.
Collection
.
Model
;
using
Sitecore
.
XConnect
.
Schema
;
using
Sitecore
.
Xdb
.
Common
.
Web
;
using
Plugin
.
Konabos
.
Loyalty
.
Components
;
using
Sitecore
.
Framework
.
Pipelines
;
using
Microsoft
.
Extensions
.
Logging
;
namespace
Konabos
.
Loyalty
.
Feature
.
ReconcilePoints
.
Pipelines
.
Blocks
{
public
class
UpdateCustomerInxDBBlock
:
PipelineBlock
<
Customer
,
Customer
,
CommercePipelineExecutionContext
>
{
private
readonly
IPersistEntityPipeline
_persistEntityPipeline
;
private
readonly
IFindEntitiesInListPipeline
_findEntitiesInListPipeline
;
public
UpdateCustomerInxDBBlock
(
IPersistEntityPipeline
persistEntityPipeline
,
IFindEntitiesInListPipeline
findEntitiesInListPipeline
)
{
_persistEntityPipeline
=
persistEntityPipeline
;
_findEntitiesInListPipeline
=
findEntitiesInListPipeline
;
}
public
override
async
Task
<
Customer
>
Run
(
Customer
customer
,
CommercePipelineExecutionContext
context
)
{
CertificateWebRequestHandlerModifierOptions
options
=
CertificateWebRequestHandlerModifierOptions
.
Parse
(
"StoreName=My;StoreLocation=LocalMachine;FindType=FindByThumbprint;FindValue=BC9B7186102910E8F34EE8D9F38138203F7555BA"
);
var
certificateModifier
=
new
CertificateWebRequestHandlerModifier
(
options
);
List
<
IHttpClientModifier
>
clientModifiers
=
new
List
<
IHttpClientModifier
>();
var
timeoutClientModifier
=
new
TimeoutHttpClientModifier
(
new
TimeSpan
(
0
,
0
,
20
));
clientModifiers
.
Add
(
timeoutClientModifier
);
var
collectionClient
=
new
CollectionWebApiClient
(
new
Uri
(
"https://cateringdemo.xconnect.dev.local/odata"
),
clientModifiers
,
new
[]
{
certificateModifier
});
var
searchClient
=
new
SearchWebApiClient
(
new
Uri
(
"https://cateringdemo.xconnect.dev.local/odata"
),
clientModifiers
,
new
[]
{
certificateModifier
});
var
configurationClient
=
new
ConfigurationWebApiClient
(
new
Uri
(
"https://cateringdemo.xconnect.dev.local/configuration"
),
clientModifiers
,
new
[]
{
certificateModifier
});
var
cfg
=
new
XConnectClientConfiguration
(
new
XdbRuntimeModel
(
LoyaltyModel
.
Model
),
collectionClient
,
searchClient
,
configurationClient
);
try
{
await
cfg
.
InitializeAsync
();
}
catch
(
XdbModelConflictException
ce
)
{
context
.
Logger
.
LogError
(
string
.
Format
(
"{0}-Error in UpdateCustomerInxDBBlock connecting to xDB : {1}"
,
(
object
)
this
.
Name
,
(
object
)
ce
.
Message
),
Array
.
Empty
<
object
>
());
}
using
(
var
client
=
new
XConnectClient
(
cfg
))
{
try
{
IdentifiedContactReference
reference
=
new
IdentifiedContactReference
(
"CommerceUser"
,
string
.
Concat
(
customer
.
Domain
,
"\", customer.Email));
Contact existingContact = client.Get<Contact>(reference, new ContactExpandOptions(new string[] { PersonalInformation.DefaultFacetKey, LoyaltyPointsFacet.DefaultFacetKey, LoyaltyCommerceFacet.DefaultFacetKey }));
if (existingContact != null)
{
//Add an identifier for the contact with the Commerce Customer Id
string identifierSource = "
LoyaltyCustomerId
";
var loyaltyCustomerIdentifier = existingContact.Identifiers.Where(i => i.Source == identifierSource).FirstOrDefault();
if (loyaltyCustomerIdentifier == null)
{
client.AddContactIdentifier(existingContact, new ContactIdentifier(identifierSource, customer.Id.ToString(), ContactIdentifierType.Known));
client.Submit();
}
//Add or Update Loyalty Points for the customer
LoyaltyPointsFacet loyaltyPointFacet = existingContact.GetFacet<LoyaltyPointsFacet>(LoyaltyPointsFacet.DefaultFacetKey);
if (loyaltyPointFacet == null)
loyaltyPointFacet = new LoyaltyPointsFacet();
loyaltyPointFacet.PointsEarned = customer.GetComponent<LoyaltyComponent>().PointsEarned;
loyaltyPointFacet.PointsSpent = customer.GetComponent<LoyaltyComponent>().PointsSpent;
client.SetFacet<LoyaltyPointsFacet>(existingContact, LoyaltyPointsFacet.DefaultFacetKey, loyaltyPointFacet);
client.Submit();
//Add or Update the Commerce Customer ID
LoyaltyCommerceFacet loyaltyCommerceFacet = existingContact.GetFacet<LoyaltyCommerceFacet>(LoyaltyCommerceFacet.DefaultFacetKey);
if (loyaltyCommerceFacet == null)
loyaltyCommerceFacet = new LoyaltyCommerceFacet();
loyaltyCommerceFacet.CommerceCustomerId = customer.Id.ToString();
client.SetFacet<LoyaltyCommerceFacet>(existingContact, LoyaltyCommerceFacet.DefaultFacetKey, loyaltyCommerceFacet);
client.Submit();
}
}
catch (XdbExecutionException ex)
{
context.Logger.LogError(string.Format("
{
0
}-
Error
in
UpdateCustomerInxDBBlock
updating customer
{
2
}
to xDB
:
{
1
}
", (object)this.Name, (object)ex.Message, customer.Id.ToString()), Array.Empty<object>());
}
}
return customer;
}
}
}
You might get the following error while the running xConnect code:
[
Error
]
[
"XdbContextLoggingPlugin"
]
XdbContext
Batch
Execution
Exception
System
.
Net
.
Http
.
HttpRequestException
:
An
error occurred
while
sending the request
.
--->
System
.
Net
.
WebException
:
The
underlying connection was closed
:
Could
not
establish trust relationship
for
the SSL
/
TLS secure channel
.
--->
System
.
Security
.
Authentication
.
AuthenticationException
:
The
remote certificate
is
invalid according to the validation procedure
.
at
System
.
Net
.
TlsStream
.
EndWrite
(
IAsyncResult
asyncResult
)
at
System
.
Net
.
ConnectStream
.
WriteHeadersCallback
(
IAsyncResult
ar
)
---
End
of inner exception stack trace
---
at
System
.
Net
.
HttpWebRequest
.
EndGetRequestStream
(
IAsyncResult
asyncResult
,
TransportContext
&
context
)
at
System
.
Net
.
Http
.
HttpClientHandler
.
GetRequestStreamCallback
(
IAsyncResult
ar
)
---
End
of inner exception stack trace
---
at
System
.
Runtime
.
ExceptionServices
.
ExceptionDispatchInfo
.
Throw
()
at
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
.
HandleNonSuccessAndDebuggerNotification
(
Task
task
)
at
Sitecore
.
Xdb
.
Collection
.
Search
.
Solr
.
SolrReader
.<
ExecuteQuery
>
d__14
`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Sitecore.Xdb.Collection.Search.Solr.SolrReader.<GetSearchResults>d__13`
2.MoveNext
()
---
End
of stack trace
from
previous location
where
exception was thrown
---
at
System
.
Runtime
.
ExceptionServices
.
ExceptionDispatchInfo
.
Throw
()
at
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
.
HandleNonSuccessAndDebuggerNotification
(
Task
task
)
at
Sitecore
.
Xdb
.
Collection
.
Search
.
Solr
.
SolrReader
.<
SearchContacts
>
d__10
.
MoveNext
()
---
End
of stack trace
from
previous location
where
exception was thrown
---
at
System
.
Runtime
.
ExceptionServices
.
ExceptionDispatchInfo
.
Throw
()
at
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
.
HandleNonSuccessAndDebuggerNotification
(
Task
task
)
at
Sitecore
.
Xdb
.
Collection
.
Repository
.<
SearchContacts
>
d__11
.
MoveNext
()
---
End
of stack trace
from
previous location
where
exception was thrown
---
at
System
.
Runtime
.
ExceptionServices
.
ExceptionDispatchInfo
.
Throw
()
at
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
.
HandleNonSuccessAndDebuggerNotification
(
Task
task
)
at
Sitecore
.
Xdb
.
Collection
.
RepositoryCountersDecorator
.<
SearchContacts
>
d__8
.
MoveNext
()
---
End
of stack trace
from
previous location
where
exception was thrown
---
at
System
.
Runtime
.
ExceptionServices
.
ExceptionDispatchInfo
.
Throw
()
at
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
.
HandleNonSuccessAndDebuggerNotification
(
Task
task
)
at
Sitecore
.
XConnect
.
Service
.
RepositorySearchInvoker
.<
Execute
>
d__7
.
MoveNext
()
published
certlm
Please add your Solr cert to the Local Computer\Trusted Root Certification Authorities.
You might get the following error while the running xConnect code:
2018
-
08
-
25
15
:
01
:
10.453
-
07
:
00
[
Information
]
XConnect
Test
Host
Application
Start
,
Machine
:
"DESKTOP-BCOM790"
,
Site
:
"cateringdemo.xconnect.dev.local"
,
AppId
:
"/LM/W3SVC/2/ROOT"
2018
-
08
-
25
15
:
01
:
11.584
-
07
:
00
[
Information
]
Certificate
Validation
Filter
Enabled
,
Thumbprint
:
BC9B7186102910E8F34EE8D9F38138203F7555BA
2018
-
08
-
25
15
:
01
:
11.585
-
07
:
00
[
Information
]
SSL
Validation
Filter
Enabled
2018
-
08
-
25
15
:
01
:
12.865
-
07
:
00
[
Information
]
SystemPerformanceCounters
Constructor
,
Instance
:
cateringdemo
.
xconnect
.
dev
.
local
,
Path
:
C
:
inetpubwwwrootcateringdemo
.
xconnect
.
dev
.
localApp_DataDiagnostics
,
CounterFilePattern
:
*.
json
2018
-
08
-
25
15
:
01
:
12.882
-
07
:
00
[
Error
]
Access
to the registry key
'Global'
is
denied
.
System
.
UnauthorizedAccessException
:
Access
to the registry key
'Global'
is
denied
.
at
Microsoft
.
Win32
.
RegistryKey
.
Win32Error
(
Int32
errorCode
,
String
str
)
at
Microsoft
.
Win32
.
RegistryKey
.
InternalGetValue
(
String
name
,
Object
defaultValue
,
Boolean
doNotExpand
,
Boolean
checkSecurity
)
at
Microsoft
.
Win32
.
RegistryKey
.
GetValue
(
String
name
)
at
System
.
Diagnostics
.
PerformanceMonitor
.
GetData
(
String
item
)
at
System
.
Diagnostics
.
PerformanceCounterLib
.
GetPerformanceData
(
String
item
)
at
System
.
Diagnostics
.
PerformanceCounterLib
.
get_CategoryTable
()
at
System
.
Diagnostics
.
PerformanceCounterLib
.
CategoryExists
(
String
machine
,
String
category
)
at
System
.
Diagnostics
.
PerformanceCounterCategory
.
Exists
(
String
categoryName
,
String
machineName
)
at
System
.
Linq
.
Enumerable
.
WhereEnumerableIterator
`1.MoveNext()
at System.Linq.Buffer`
1.
.
ctor
(
IEnumerable
`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`
1
source
)
at
Sitecore
.
XConnect
.
Diagnostics
.
PerformanceCounters
.
SystemPerformanceCounters
.
Initialize
(
String
counterFilePattern
)
2018
-
08
-
25
15
:
01
:
13.331
-
07
:
00
[
Information
]
Create
"XdbContextLoggingPlugin"
2018
-
08
-
25
15
:
01
:
13.341
-
07
:
00
[
Information
]
Register
"XdbContextLoggingPlugin"
Please add your xConnect site app pool user to the Performance Monitor Users group.
Follow us on Twitter Follow us on LinkedIn Follow us on YouTube
Akshay is an nine-time Sitecore MVP who has spent more than a decade working exclusively on Sitecore projects.
In addition to his work as a solution architect, Akshay is also one of the founders of SUGCON North America 2015, SUGCON India 2018 & 2019, Unofficial Sitecore Training, and the Sitecore Slack.
Akshay founded and continues to run the Sitecore Hackathon. As one of the managing partners of Konabos Consulting, Akshay will continue to work with clients to lead projects and mentor their existing teams.