Thursday, July 28, 2011

Manually configuring a Tridion 2011 .NET Content Deployer Instance

I'm a big fan of doing "manual" installations of the Tridion Content Delivery layer (be it for .NET or Java, as is probably clear here) and I had not got around for a while to do a complete .NET setup so I could document it somehow.

Until today.

Please note: the steps below are for a 64-bit server. On a 32 bit server you need a couple more files, copied from the x86 installation folder.

These are the steps taken:
Get your files right:
The Hotfix rollup #1 shipped with quite a few updated jar files, but somehow not all files are shipped (cd_tcdl, cd_dynamic and probably a few others are missing, and you need the originals from the 2011 installer). Solution: copy the updated jar files from the hotfix rollup _over_ the files shipped with 2011.

Create your HTTP deployer website:
This is the basic structure for the site:
/
/bin
/bin/config
/bin/lib
In the root, ( / ) drop the httpupload.aspx
In /bin, drop the following 4 dlls:
  • netrtsn.dll
  • Tridion.ContentDelivery.Configuration.dll
  • Tridion.ContentDelivery.dll
  • xmogrt.dll
in /bin/config, place the following configuration files (more details on what goes in these files later):
  • cd_deployer_conf.xml
  • cd_storage_conf.xml
  • logback.xml
in /bin/lib, drop a s***load of jar files...
All jar files from [ContentDeliveryInstall]/java/third-party-lib
The following files from [ContentDeliveryInstall]/java/lib:
  • cd_broker.jar
  • cd_cache.jar
  • cd_core.jar
  • cd_datalayer.jar
  • cd_deployer.jar
  • cd_linking.jar
  • cd_model.jar
  • cd_tcdl.jar
  • cd_upload.jar
And, last but certainly not least, add your jdbc (sqljdbc or ojdbc) driver to this folder.

Configuration

Obviously you must change the settings in these files to match your server configuration (sorry if it doesn't display very well on this blog, copy/pasting should work).

cd_deployer_conf.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!-- The Tridion Content Distributor Deployer configuration specifies all
    configuration values required to receive and deploy content to a delivery system. -->
<Deployer Version="6.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:noNamespaceSchemaLocation="schemas/cd_deployer_conf.xsd">
    <Processors>
        <Processor Action="Deploy" 
   Class="com.tridion.deployer.Processor">
            <Module Type="SchemaDeploy" 
    Class="com.tridion.deployer.modules.SchemaDeploy"/>
            <Module Type="PageDeploy" 
    Class="com.tridion.deployer.modules.PageDeploy">
                 <Transformer Class="com.tridion.deployer.TCDLTransformer"/>
            </Module>
            <Module Type="BinaryDeploy" 
    Class="com.tridion.deployer.modules.BinaryDeploy"/>
            <Module Type="ComponentDeploy" 
    Class="com.tridion.deployer.modules.ComponentDeploy"/>
            <Module Type="TemplateDeploy" 
    Class="com.tridion.deployer.modules.TemplateDeploy"/>
            <Module Type="PublicationDeploy" 
    Class="com.tridion.deployer.modules.PublicationDeploy"/>
            <Module Type="TaxonomyDeploy" 
    Class="com.tridion.deployer.modules.TaxonomyDeploy"/>

            <Module Type="ComponentPresentationDeploy"
    Class="com.tridion.deployer.modules.ComponentPresentationDeploy">
                <Transformer Class="com.tridion.deployer.TCDLTransformer"/>
            </Module>
            <Module Type="StructureGroupDeploy" 
    Class="com.tridion.deployer.modules.StructureGroupDeploy"/>
        </Processor>
        <Processor Action="Undeploy" 
   Class="com.tridion.deployer.Processor">
            <Module Type="PageUndeploy" 
    Class="com.tridion.deployer.modules.PageUndeploy"/>
            <Module Type="ComponentPresentationUndeploy" 
    Class="com.tridion.deployer.modules.ComponentPresentationUndeploy"/>
            <Module Type="TaxonomyUndeploy" 
    Class="com.tridion.deployer.modules.TaxonomyUndeploy"/>
            <Module Type="StructureGroupUndeploy" 
    Class="com.tridion.deployer.modules.StructureGroupUndeploy"/>
        </Processor>
    </Processors>
    <Queue>
        <Location Path="c:\tridion\incoming" 
   WindowSize="20" Workers="10" Cleanup="true" Interval="2s"/>
    </Queue>
    <HTTPSReceiver MaxSize="10000000" 
  Location="C:\tridion\incoming" InProcessDeploy="true"/>
     <License Location="c:/Program Files(x86)/Tridion/config/cd_licenses.xml"/>
    <TCDLEngine>
        <Properties>
            <!-- Default code generation will always be targetted towards the use of tag libraries and
                  server controls. Uncomment these lines to drop that behaviour -->
            <Property Name="tcdl.dotnet.style" Value="controls"/>
            <Property Name="tcdl.jsp.style" Value="tags"/>
        </Properties>
    </TCDLEngine>

</Deployer>

cd_storage_conf.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration Version="6.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="schemas/cd_storage_conf.xsd">
  <Global>
    <ObjectCache Enabled="false">
      <Policy Type="LRU" Class="com.tridion.cache.LRUPolicy">
        <Param Name="MemSize" Value="16mb"/>
      </Policy>
      <Features>
        <Feature Type="DependencyTracker" Class="com.tridion.cache.DependencyTracker"/>
      </Features>
    </ObjectCache>
    <Storages>
      <Storage Type="persistence" Id="sqlserver" dialect="MSSQL" Class="com.tridion.storage.persistence.JPADAOFactory">
        <Pool Type="jdbc" Size="5" MonitorInterval="60" IdleTimeout="120" CheckoutTimeout="120" />
        <DataSource Class="com.microsoft.sqlserver.jdbc.SQLServerDataSource">
          <Property Name="serverName" Value="localhost" />
          <Property Name="portNumber" Value="1433" />
          <Property Name="databaseName" Value="Tridion_Broker" />
          <Property Name="user" Value="TridionBrokerUser" />
          <Property Name="password" Value="tridion" />
        </DataSource>
      </Storage>
      <Storage Type="filesystem" Class="com.tridion.storage.filesystem.FSDAOFactory" Id="iisFile">
        <Root Path="c:\inetpub\wwwroot" />
      </Storage>
    </Storages>
  </Global>
  <ItemTypes defaultStorageId="sqlserver" cached="false">
    <Item typeMapping="Page" cached="false" storageId="iisFile"/>
    <Item typeMapping="Binary" cached="false" storageId="iisFile"/>
  </ItemTypes>
  <License Location="c:/Program Files (x86)/Tridion/config/cd_licenses.xml"/>

</Configuration>
logback.xml:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
    <!-- Properties -->
    <property name="log.pattern" value="%date %-5level %logger{0} - %message%n"/>
    <property name="log.history" value="7"/>
    <property name="log.folder" value="c:/tridion/log/website"/>
    <property name="log.level" value="debug"/>

    <!-- Appenders -->
    <appender name="rollingCoreLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.folder}/cd_core.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>${log.history}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <prudent>true</prudent>
    </appender>

    <!-- Loggers -->
    <logger name="com.tridion" level="${log.level}"/>
    <root level="OFF">
        <appender-ref ref="rollingCoreLog"/>
    </root>
</configuration>

Now you have to create a website in IIS that uses this folder as its root folder. If using 2008 R2 you may want to change the application pool identity to Network Service, and you will have to give this user WRITE permissions on the filesystem storage location, as specified in cd_storage_conf.

And that's pretty much it. Configure a Publication Target that uses your new website:/httpupload.aspx and you're ready to go.

Last tip: If you need to publish large packages (think > 4 MB or whatever is the low limit for an IIS POST by default) create a web.config for this website and put the following inside:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="false" targetFramework="4.0" />
    <httpRuntime maxRequestLength="2097151"
    executionTimeout="600"/>
  </system.web>
  <system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="2000000000" />
      </requestFiltering>
    </security>
  </system.webServer>
</configuration>

Thursday, July 21, 2011

Spicing the community up

As the most visible face of the SDL Tridion MVP Selection Panel I get asked plenty of questions about the selection process, the nominations, the qualifications of the MVPs, etc.

Here's an FAQ to try to sort this thing once and for all:

How do I get to be an MVP?
Very simple:
  1. Contribute to the community. This includes - but is not limited to - twitter, facebook, linkedin, personal blogs, the Tridion Forum, SDLTridionWorld
  2. Get nominated by following the instructions on the MVP Program page
Can I nominate myself?
Yes.


What is a Community Builder?
An MVP that works for SDL.

Who are the Community Builders?
This information is not publicized since we want to promote external MVPs - partners, customers, independents. However, we felt that some contributions from our own people were too good to go unpunished so SDL employees receive a Community Builder award instead. Letting the wider world know about "person X" being a Community Builder is left to the person's own discretion.

Why is {person A} an MVP and not {person B}?
This is one of the most common questions I get. Well, likely because {person B} did not follow the steps outlined above on "How do you get to be an MVP?". The MVP program's goal is NOT to identify the best Tridion resources out there. In many cases, the current MVPs would not even qualify to a "Top 20" of the best Tridion resources in the world (in my not-so-humble opinion). They get the award not because of what they know (though that helps) but because of what they do. Every time an MVP answers a question in the Forum, hundreds of people (potentially) learn from it. Every time an MVP blogs something, the whole world can learn from it. Every time {person B} does a very successful implementation and does not tell the world anything about the solutions chosen, we all lose.

Are you saying MVPs are not the best of the best?
Yes, I am saying that being an MVP does not mean you are better than anyone else. It means you share more than others.


Now that this little FAQ is out of the way...
What the **** are our current MVPs doing? It sure has been a long time since I read anything good by any of them (exception made to Walter that keeps on pushing good stuff out).