Friday, February 28, 2014

SDL Tridion 2013 SP1 - How to Setup a 2nd Broker

Whenever I've come across installing Tridion, I've always installed at least two broker databases, and lately three if you count the Session Preview broker as well.  The first broker is for Staging websites, while the second is used for Live sites.

As is the case with a repetitive action, the more you do it, the faster and better you become at it.
Here are several pseudo-steps as an easy recipe to get you through this setup fast as fast can be in Tridion 2013 SP1.

1. Install the actual database and know the database credentials ahead of time*: run the Powershell script
& '.\Install Content Data Store.ps1' 

2. Name your broker something different than what is in the database already (eg. Tridion_Broker_Staging)

3. Update your (second) Deployer cd_storage_conf.xml with the new broker information and configure how you want different item types to be handled.  A second separate deployer is required to write to the new database.

4. Update (another) corresponding website cd_storage_conf.xml to show content from the second broker.  A separate website is necessary as well to show content stored in the new broker.

5. Loop back into the Tridion Content Manager Explorer and create the necessary [Staging] target type and publication target(s).
Specify the deployer information based on type installed and apply the publications you want to store content in the new broker.

.. and voila, the second broker should be active and receiving content when you publish.

Happy brokering!



References (login required):

Saturday, February 8, 2014

Quick Check List for SDL Tridion 2011 SP1 Personalization and Profiling Setups

In SDL Tridion 2011 SP1, setting up pesonalization and profiling can be somewhat challenging given the range of configuration touch points spans both the Content Manager and the Content Delivery systems.
If you are looking for an installation, configuration and implementation path, you could likely follow these steps (depending on whether this is .NET or Java based): 


1. Check the Target Publishing Language in the Publication Target is dynamic (JSP/ASP/REL)

2. Check the cd_deployer_conf.xml file includes TCDLTransformer class, for PageDeploy for example

3. Update the cd_storage_conf.xml (or cd_broker_conf.xml if still using that) to enable Item Types for the elements you want to track (eg. PageTracked, Timeframe etc)

4. Update the cd_wai_conf.xml to represent your website and settings for your personalization and profiling requirements such as host, cookies, tracking info

5. Update the web.config to support the httpModule TridionWAIHttpModule

6. Restart Content Delivery services and web servers for changes to take place

6. Proceed to enable item tracking such as Component and Page Template tracking in the CMS using template building blocks

7. Check if tracking is working after publishing your changes from the CMS by viewing content from a browser

8. Continue to implement personalization and profiling requirements using CMS functionality and API calls and test they function as expected after publishing and viewing pages from a browser 


Additional references for Personalization and Profiling can be found below.


Thursday, January 30, 2014

Tips for Troubleshooting the SDL Tridion Transport Service

The SDL Tridion Transport Service is step two of the content distribution process.  This service is somewhat mystical for two reasons:  it resides on both the Content Manager and Content Delivery systems and it is more difficult to troubleshoot than other services.
Since I've been on a quest lately to shine the light on the unknown, let's take a look at it!

The Transport Service is a mechanism which gathers published items and their dependencies into a package.  It then submits this package from a Content Manager to a Content Delivery system by using sending and receiving modules enabled for different protocols.  These protocols are activated in the cd_transport_conf.xml file for the Content Manager and in the cd_deployer_conf.xml for Content Delivery.

* Local file
* HTTP
* HTTPS
* FTP
* SFTP
* SSHFTP

Under certain conditions, the Transport Service may not start, or start and stop immediately, or otherwise report an error message during the lifecycle of the publishing process.

What can you do to troubleshoot it?  Here is a quick list to walk you through a number of checks:
1. Windows event logs (Tridion.evtx and Application)
Look for messages such as the one below, which is a pretty clear indication that the java version the Transport Service was trying to use could not be loaded (the issue in step 2).

"The description for Event ID 100 from source TCDTransportService cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer. 
If the event originated on another computer, the display information had to be saved with the event. 
The following information was included with the event: 
Could not load Java runtime libraries at C:\Program Files (x86)\Java\jre7\bin\client\jvm.dll" 

2. Does the java version installed match the version required by the specific SDL Tridion version installed?
Some machines are configured to pop up a small notification icon to nudge you  forward to the next java update. It's easy to click on it and accidentally install an unsupported version.  Make sure you have the right version, use "java -version" from a command prompt.

3. Publisher Service will not start if the Transport Service does not start
There is a dependency between the Publisher Service and the Transport Service, hence if you notice the Publisher Service does not start, it may be an indication something is off with the Transport Service

4. The transport service log
This log is located on the Content Manager server.  When set in debug mode from the logback.xml file, it can provide more details around the processing involved in transporting items, and therefore potentially narrow down something more specific about an issue.

5. Is a custom transport used, if so, is it written, configured and used properly?
Occasionally, someone may want to use a protocol other than what is available by default.  This is possible by creating a class which implements the com.tridion.transport.connection.TransportConnector java interface, and creating the appropriate Sender and its protocol schema.
Validate all steps were followed accurately as described in the documentation (login required)
http://sdllivecontent.sdl.com/LiveContent/content/en-US/SDL_Tridion_2011_SPONE/task_E724DA16924F4CF4A3E00B160445F2DA

6.  HTTPS Uploads
Should HTTPS be chosen for transporting items, the only way this can take place if if there is a certificate added in the keystore, so that the transport mechanism is allowed to access its destination.  The certificate may be imported into the default CACERTS keystore or a custom one.
Look for an entry such as the one below to tell if there is a custom store in use:

<Sender Type="HTTPS" Class="com.tridion.transport.connection.connectors.HTTPSTransportConnector">
  <KeyStore Path="c:\mydir\myks.keystore" Secret="mypassword" />
</Sender>
  
An incorrect configuration in cd_transport_conf.xml such as a KeyStore node in cd_transport_conf.xml missing from the HTTPS Sender will cause the Transport Service to fail.
The step by step procedure to add a keystore is explained in the documentation (login required)
http://sdllivecontent.sdl.com/LiveContent/content/en-US/SDL_Tridion_2011_SPONE/concept_90BCCB544F8E46F4AF88EDCDAC17987F

7. Transporting using a proxy
When sending content across servers, from an internal network out to an external public one, many organizations use proxies to protect the data.  It's possible to misconfigure this proxy and cause the transport to break down.  The proxy configuration differs based on type of protocol used, as well as the type of proxy, generic or application specific, and so the changes to watch for will be done in the Publication Target and/or the registry, full details available in the documentation (login required).
http://sdllivecontent.sdl.com/LiveContent/content/en-US/SDL_Tridion_2011_SPONE/concept_455C61B06FAB4502B5AF573332E6C33E

8. Is the cd_license missing?
It may be easy to forget about the cd_license.xml file on the Content Manager server, and this is definitely a requirement for the Transport Service to operate.  

9. Last but not least, simple as it may be, do not forget to restart the Transport Service after changes made to (re)configure it.

As Alfred Pennyworth (Batman Begins, 2005) best put it: "And why do we fall sir?  So that we can learn to pick ourselves up."
Should the Transport Service happen to behave unusually, grab your flashlight, follow my trail and see how quickly you can demystify the strange..

Sunday, January 12, 2014

7 Things I bet You Didn't Know about Experience Manager

In the past few weeks, I've had a chance to shine the flashlight a little closer on the SDL Tridion Experience Manager interface of the Content Management System, especially so for the new SDL Tridion 2013 SP1 version out since the first week of December.
Here is a list of things I uncovered and found worth noting:

1. The SDL Tridion Live Documentation for 2013 SP1 has a video on the entire Experience Manager install, configuration plus installation steps.  There are architecture illustrations as well, easy to follow if you look for the 1-2-3 steps marked on the diagrams. 
http://sdllivecontent.sdl.com/LiveContent/content/en-US/SDL%20Tridion%20full%20documentation-v1/GUID-3C70F892-69F4-4FEE-922D-39F1AFEBD539

2. The Content Manager Explorer Dashboard has been morphed into a slide-out navigation, therefore any extensions created for Experience Manager and previously visible on the Dashboard need to be re-coded for the slide-out navigation panel.  

3. You must remember to re-install Default Template Building Blocks from TemplateBuilder to ensure the newly updated TBBs are introduced in the Content Manager.

4. The Dreamweaver call RenderComponentField() is deprecated and replaced with the following new Dreamweaver calls.  The main reason for this is to allow multivalued embedded fields to be editable from Experience Manager, something many have been looking forward to.

@@FieldStartMarker(FIELDNAME)@@ and @@FieldEndMarker@@

@@FieldValueStartMarker()@@
      @@GetFieldValue(FIELDNAME, 0)@@
@@FieldValueEndMarker()@@

They also must be used in proper order or else will not output the equivalent tags which are recognizable by Experience Manager.

@@FieldStartMarker("fieldname")@@
     @@FieldValueStartMarker()@@
          @@GetFieldValue("fieldname")@@
     @@FieldValueEndMarker()@@
@@FieldEndMarker()@@

5. The SessionPreview token session length is configurable in cd_storage_conf.xml.  Update the <Timeout> element, measured in milliseconds, for example 60000 for 1 minute, 120000 for 2 minutes and so on.  

<Wrappers>
  <Wrapper Name="SessionWrapper">e
    <Timeout>60000</Timeout>
    <Storage Type="persistence" Id="db-session" dialect="MSSQL" Class="com.tridion.storage.persistence.JPADAOFactory">
      <Pool Type="jdbc" Size="5" MonitorInterval="60" IdleTimeout="120" CheckoutTimeout="120" />

The session length accounts for the little trip Experience Manager takes while a user clicks UpdatePreview to save new changes in the browser and the session database.

6. Enabling multiple targets for Session Preview (eg. Live and Staging) may cause ExperienceManager not to work. Experience Manager should only run on Staging type sites, not on Live.

7. There is a number of fixes provided exclusively for Experience Manager in 2013 SP1, and they vary from editorial to technical.  For instance, when clicking on "Finish Editing" the latest changes done on the page are shown during reloading of the page.

So if you plan on tackling the installation, configuration and implementation for Experience Manager keep the above pointers in mind when you do and you will definitely have a brighter go of it!


Tuesday, October 8, 2013

Under the Magnifying Glass - Cache Channel Service Troubleshooting Steps

Lately I found myself spending a lot more time troubleshooting the Cache Channel Service, and learning more and more about it. Funny how the more I fixed different issues, the more I started liking it!  
In general, most issues seemed to revolve around connections between the three players involved: the Cache Channel Service, the Deployer and the Website.

So let's track them one by one and place them under the magnifying glass to discover what went wrong.

  • First off, be clear on what type of CCS is installed, Windows service or Java process? Then check documentation for configuration and correct installation steps
  • Is CCS running?  Test it with telnet.
    • Telnet 127.0.0.1 1099
    • If the service is running, you should get a blank screen
    • If the service is not running: you will likely see the following "Could not open connection to the host, on port 1099: Connect failed"
    • Always restart the Cache Channel service before restarting the Broker / Deployer

    • Is CCS communicating on the same port as the Deployer and Website Cache?  Think of it as people trying to call each other on different phone numbers!  If it doesn't match, that call is not going to happen..
      • In Windows, check that the registry key HKEY_LOCAL_MACHINE->SYSTEM->CurrentControlSet->Service->TCDCacheService shows the port, otherwise, the CCS is running on default port 1099 
    • Is CCS running in a 64-bit JVM (as it is a 64 bit windows service)
    • What about that RMIChannel setting?  In principle, in RMI, the first party, in our case the Cache Channel Service will open a socket to listen to incoming requests on a specific port.  If a request is received (such as from the Deployer/Website), a different port is used to initiate and respond to it.  This other port is typically chosen by the underlying operating system from a fairly large range available, which may be problematic in environments with firewalls holding a tight control on what ports are made available*.  It is possible however to exert tighter control on this, by using a combination of configuration settings and programming applied when the (web) application starts.
      • Set <RMIChannel Port="xyzt"> on all Tridion configuration files where the setting is available
      • In Java, set com.tridion.util.TridionRMISocketFactory.setRMIChannelListener(listenerPort);
      • In .NET, set Com.Tridion.Util.TridionRMISocketFactory.SetRMIChannelListener(listenerPort)
    • Check firewalls, windows and custom software, are any ports blocked by firewalls?
    • Restart CCS - simple but may be just as effective in applying recent configuration changes.  If running it as a Windows service, stop and start the service.  If running it as a process, try the following** (change CCS path if yours is different):
      • > cd opt/tridion/cds/common/scripts
      • > ls -la
      • > ./start_ccs.sh stop
      • > ./start_ccs.sh start
      • > ./start_ccs.sh status
    • Try using 'localhost' if all parties are on the same machine
    • Check cd_core logs from Deployer, web application, CCS (if running in its own jvm and therefore creating own logs)
    • In logs, check communication from each party to see if the Deployer wrote notifications as well as if the application received notifications, good reference on SDL Tridion World***
    • Run netstat -a from the command prompt to get a list of all active connections the computer is listening too (including TCP and UDP ports) then check if the ports you are using are open
    • Google the errors seen in the logs, there may be explanations outside of Tridion!
    • Check other Content Delivery settings in the documentation to take advantage of some pretty nifty settings the cache is capable of like the "FlushCacheDuringDisconnectInterval" which can be used to control the behavior of the cache even when disconnected (keep items in cache or flush on first disconnect)
    By now, I hope the magnifying glass was put away as one of the checks above helped restore caching to its duty, but if not, there is a entire armada of magnifying glasses on tridion.stackexchange.com.  Try posting your special circumstances there!

    Cheers, and go have fun tracing!


    http://www.netcluesoft.com/rmi-through-a-firewall.html
    ** The Tridion LiveDoc will tell you how you can create your own scripts to start/stop CCS
    *** http://www.sdltridionworld.com/articles/sdltridion2011/analyzing_object_cache.aspx

    Sunday, March 31, 2013

    SDL Tridion 2011 SP1 - Bypass first workflow activity

    Back in my consulting days, when delivering training on workflow, I would start by explaining what workflow is and how in Tridion, workflow's meaning is not the same as what a business would understand its own business workflow to be. Then I would explain what this difference was and proceed along to describe what each little workflow building block is used for.

    In SDL Tridion 2011 (and 2009), all items starting workflow automatically enter a manual activity assigned to everyone with the intent of handling or better yet locking any editing or update henceforth. *

    As useful and purposeful as this action was, inevitably, I would always get the following question: "This is great! Now, how can we bypass it?"

    Seeing as there are indeed reasons to bypass the first activity, for example if there is a need to introduce a decision activity for logic to direct flow of user actions differently based on some criteria, below is some code that will accomplish this from an Event System.

    public class TestFastForward : TcmExtension {
    public TestFastForward() {
    //EventSystem.Subscribe(OnComponentSavePost, EventPhases.TransactionCommitted); EventSystem.Subscribe< Component , CheckInEventArgs >(OnComponentCheckIn, EventPhases .TransactionCommitted);        
    }        
    //private void OnComponentSavePost(Component comp, SaveEventArgs args, EventPhases phases) private void OnComponentCheckIn( Component comp, CheckInEventArgs args, EventPhases phases) {            
    try {                
    XmlElement xmlElement = comp.ToXml();                
    XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager (new NameTable());                
    xmlNamespaceManager.AddNamespace( "tcm" , "http://www.tridion.com/ContentManager/5.0" ); String activityInstanceId = xmlElement.SelectSingleNode("//*[local-name()='ActivityInstance']" , xmlNamespaceManager).Attributes[ "xlink:href" ].Value;                
    ActivityInstance activityInstance = new ActivityInstance( new TcmUri (activityInstanceId), comp.Session);                
    ActivityFinish activityFinishData = new ActivityFinish ( "Automatically finished activity " + activityInstance.Title, null , comp.Session);                
    ActivityInstance nextActivity = activityInstance.Finish(activityFinishData);            
    }            
    catch (Exception ex) { throw new Exception(ex.Message);            
    }        
    }

    In the code above, I retrieve the ActivityInstance from the current component in the active session. Then I use information from it to advance to the next activity, whatever this may be as designed in the Visio diagram. Even though an item is in workflow the CheckIn event is still called when an Editor clicks Save & Close, the same code will work in the post Save event for an item.

    * In SDL Tridion 2013, items do not automatically enter workflow as soon as an item is created or edited, but rather when an Editor clicks Enter Workflow.

    Sunday, February 17, 2013

    Easy Breezy SDL Tridion 2011 CoreService Setup

    1. Create .NET console application
    - File - New - Project

    2. Add references
    C:\Program Files\Tridion\bin\client\
    - Tridion.ContentManager.CoreService.Client.dll
    - (.NET) System.ServiceModel.dll
    - (.NET) System.Runtime.Serialization.dll

    3. Add namespaces
    - using Tridion.ContentManager.CoreService.Client;

    4. Copy CoreService configuration
    - Tridion.ContentManager.CoreService.Client.dll.config
    to application configuration file
    - App.config (Project - Add New Item - Application Configuration File)

    5. Connect the client using a specific binding
    SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient("netTcp_2011");

    6. Code away..
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Tridion.ContentManager.CoreService.Client;
    namespace CoreServiceApp
    {
    class Program
    {
    static void Main(string[] args)
    {
    SessionAwareCoreServiceClient coreServiceClient = new SessionAwareCoreServiceClient("netTcp_2011");
    Console.Write("Connected to CoreService with user " + coreServiceClient.GetCurrentUser().Title + " in session " + coreServiceClient.GetSessionId());
    //code..

    coreServiceClient.Close();
    }
    }
    }