Showing posts with label content delivery. Show all posts
Showing posts with label content delivery. Show all posts

Sunday 28 July 2019

Manage SDL Microservice using Jenkins

As a developer, if have the access to servers, to monitor, start/stop, reading logs of SDL Microservice your life is very easy, but when we work in a cage environment and you don't have access to servers due to policies or your client has to follow certain standards such as "PCI" and stuff like that as a DEV you don't get the direct access on those machines.

Using Powershell, Yes we can do that, but what will happen when you don't have the permission to run Powershell as well and I worked on a project where, as a developer, I didn’t have the permission to run Powershell as well.

Well, In that case, we ask the DevOps to do this job for us because they are the one having all the access, but this could be a time-consuming process as well, log a ticket and then someone from DevOps address that and as a developer, we might be required to start/stop and see logs of Microservice multiple times.

There is another scenario where you have your content delivery on the Linux box, not all your developers are very familiar with the Linux commands. 

As a best practice, we should always use proper tools in such a scenario, and today we will see how we can configure Jenkins to start/stop/restart SDL Microservices.

Installing Jenkins is really quick and it takes very less time to configure it.

1. Download Jenkins.
2. Open up a terminal in the download directory.
3. Run java -jar jenkins.war --httpPort=8080. Refer screenshot 1
4. Browse to http://localhost:8080.
5. Follow the instructions to complete the installation.

Run the Jenkins.war
Jenkins is installed successfully and We have the initial password to login 

Next is let's configure the Jenkins

Hit the URL in the http://localhost:8080 this is the default port on which Jenkins runs you can change that. It will ask you the first time login secret key.

Initial password 
Next is select the defaults option to configure the Jenkins

Default feature
You can always install other plugins as well from the Manage Jenkins section

Once everything is configured you will see this screen

Jenkins is ready!!

Next is create a job that will start/stop/restart the SDL microservice

Click on create new job

I have created the following three jobs to stop/start and restart Tridion microservice using  Powershell commands we can sh commands in case of LINUX.

Tridion Services

Console output of Restart Deployer Service

Output

For monitoring the health and traffic on the machine we can use Jenkins Monitoring feature.
Go to:- http://localhost:8080/monitoring





Here you will get the necessary information related to the system health using Jenkins,  you can always use any other tool to do this.

Happy Coding and Keep Sharing!!!


Sunday 16 June 2019

Extending Content Delivery Storage in SDL WEB 8.5 - Part 3

In the last blog, we saw what happened when we publish a new component, it only calls the create method, but when we re-publish an item it first calls the remove method and then create.

Remove Method


public void remove(int publicationId, int componentId, int componentTemplateId, ComponentPresentationTypeEnum componentPresentationType)
throws StorageException
{
log.debug("Custom storage remove Method");
super.remove(publicationId, componentId, componentTemplateId, componentPresentationType);
log.debug("Custom storage remove Method :- "+componentId);
 
}
Re-Publish an item


As you can see when I re-published an item, we have remove method invoked first and then create method. Next, is un-publish an item and see how it works/ in what sequence.


Un-Publish an Item

When we publish a new item only create method is called, re-publishing will call the remove method and then create and finally in un-publish only remove method is called.   


In the last two blogs, we learned how to set up and configure the project to build storage extension and Publishing a new item and in this blog, we saw other functionalities as well and how they are invoked, in what sequence/order, with this approach we can add/update/remove DCPs in custom storage e:g SOLR, ElasticSearch, MongoDB, etc.

This data can further be used for analytics and for third-party applications.


Happy Coding and Keep Sharing !!!



Extending Content Delivery Storage in SDL WEB 8.5 - Part 2

In the previous blog, we set up the project and configured all the required config and based on that we published a DCP and saw custom logs are available which means everything is working fine.

Today we are going to read the content of DCP and will see how Storage Extension work when we publish, re-publish and un-publish an item.

The Content is available in the form of Bytes and we need to convert that, below is the code snippet that will allow you to access the DCP content in your custom code.

public void create(ComponentPresentation itemToCreate, ComponentPresentationTypeEnum componentPresentationType)
throws StorageException
{
          super.create(itemToCreate,componentPresentationType);
          log.debug("Custom Code Create Method COMID :- " + itemToCreate.getComponentId());
          log.debug("Custom Storage create Method:- "+ itemToCreate.getContent());
          log.debug(String.valueOf(itemToCreate.getComponentId()));
          byte[] dcpComponent= itemToCreate.getContent();
          try
          {
                  componentPresentation = new String(dcpComponent,"UTF-8");
                  log.debug("Custom Storage create DCP :- " + componentPresentation);
          }
          catch (UnsupportedEncodingException ex)
          {
                  log.error("Custom Storage create Unsupported " + ex);
          }

}

DCP content

Publish a new component and in the deployer log file, you will see the DCP content but what will happen when we re-publish the same component or un-publish this. How we are going to manage that in the custom code, will see in the next blog, until then.


Happy Coding and Keep Sharing !!!





Monday 3 June 2019

Custom Deployer Extension in SDL WEB 8.5 - Purge Cache Part - 2

In the previous post, we set up the custom deployer project, discussed its requirement and the use of deployer extension. Today, we are going to continue to use that same project and implement a real-life use-case.

Background:- In our current project we are using SDL WEB 8.5 and .NET DXA 1.8 and to improve the performance of the web application we implemented the custom caching with cache expires after 15 mins, but the business team has this requirement that they want to see the content "Real-time", no delay whenever the publish any new content.

Based on their requirement we came up with this approach and decided to write a custom deployer extension. So, whenever the author publish the page(s), the deployer extension will trigger and clear the cache of that particular page based on the URL extracted from PageMetaData.

In the below code snippet we are reading the page relative URL retrieved from PageMetaData and with the help of string manipulation we've created the absolute URL and based on the Query String parameter we trigger the code to purge the cache. Check the HTTP response code it should be 200 in the logs and refresh the web page to check the latest content.

 // This is called once for each Transport Package that is deployed.  
      @Override  
      public void process(TransportPackage data) throws ProcessingException   
      {  
            log.debug("This is custom logs");  
            String USER_AGENT = "Mozilla/5.0";  
            log.debug("PublicationId : " + String.valueOf(data.getProcessorInstructions().getPublicationId().getItemId()));  
           try  
           {  
            log.debug("Custom Code :- Entered in the try block");  
            PageMetaData pageFile = (PageMetaData)data.getMetaDataFile("Pages");  
            log.debug("Custom code :- Reading PageMetaData");  
            if (pageFile != null)  
      {  
        List<Page> pages = pageFile.getPages();  
        for ( Page page : pages )  
        {  
             log.debug("Custom code :- For loop to get the page url ");  
             log.debug("http://localhost:92"+page.getURLPath()+"?ClearCache=true");   
             String URL = "http://localhost:92"+page.getURLPath()+"?ClearCache=true";  
             URL obj = new URL(URL);  
             HttpURLConnection con = (HttpURLConnection) obj.openConnection();  
             con.setConnectTimeout(5000);  
             log.debug("Custom code :- timeout");  
             con.setRequestMethod("GET");  
             con.setRequestProperty("User-Agent", USER_AGENT);  
             int responseCode = con.getResponseCode();  
             log.debug("Response Code : " + responseCode);  
             if (responseCode == HttpURLConnection.HTTP_OK)  
             {  
              log.debug("Custom Deployer, Cache has been removed and the responseCode is : " + responseCode + "- for URL " + URL);  
             }  
             log.debug("Page ID :" + String.valueOf(page.getId().getItemId()));  
        }  
      }  
            log.debug("Purging is done !! Please check the web page!!");  
           }  
           catch (Exception e)  
     {  
        log.error("Could not get path for publication.", e);  
        return;  
     }  
  }  

Logs generated by the deployer.

Deployer Logs


With the help of the deployer extension, we were able to achieve and deliver the real-time experience and still managing the performance of the site using cache.


Happy Coding and Keep Sharing !!!



Saturday 13 April 2019

SDL Tridion sites 9 PCA with REACT - Part 2

In the previous post, we saw how to set up the project using Apollo Client, ReactJS and interact with Tridion Sites 9 PCA. We also build a new schema, Dynamic CT and published 3 components using the Dynamic CT in order to retrieve them via PCA (GraphQL).

In the last exercise, we rendered the list of Dynamic News Components on the Landing page. Today we are going to continue using the same code and build the Details page and later on will see the deployment process and how to deploy ReactJs App.

So, let's start with the News details page, we already created the landing page and while doing that we had sufficient information to get the DCP of that particular component. If you have noticed in the code or screenshot from my last blog the Href that I've created for each News and Article items contains the combination of ItemId and CT and we need that same combination to get the Component Presentation.

DCPs with ItemID-CT available on Landing Page

Here are the JSX and Graphql code to render the News details page

News Detail Page

Here is the News and Article Details page again not a very attractive UI 😊.

Details Page

Let's build the App and see how's the production-ready build looks like. The below commands build the deployment package after npm build we need to run serve -s from the build folder and this will spin the Website

 $ npm run build
 $ serve -s

Build Package

Final Output 

Final Build

The updated code is available on GitHub and in the next blog, we will see more features works until then.

Happy Coding and Keep Sharing !!!


SDL Tridion sites 9 PCA with REACT

Tridion sites 9 PCA is getting popular more and more every day, and today in this blog, we will be creating an app using Apollo Client to communicate with SDL Tridion GraphQL API. We will integrate Apollo Client with ReactJS, but you can use it with several other client platforms as well.

Setting Up The Project


To get started we first need to set up a new React project. The easiest way to do so is to use create-react-app. This script creates a new React project.
 npm install -g create-react-app react-graphql  
 cd react-graphql  
 npm start  

with this, you will have the default app up and running on port number 3000, This is initiating a new basic React project in the newly created project folder react-graphql. By using the npm start to command the live-reloading development web server is started and the output of the default React project can be accessed in the browser:

Default ReactJS

In order to work with GraphQL, we have to install Dependencies. The next step is to install the needed dependencies.

  • apollo-boost: Package containing everything you need to set up Apollo Client
  • react-apollo: View layer integration for React
  • graphql-tag: Necessary for parsing your GraphQL queries
  • graphql: Also parses your GraphQL queries
The installation of these dependencies can be done by using the following NPM command

 $ npm install apollo-boost react-apollo graphql-tag graphql  

Project Structure 
As you can see I've imported react-apollo in order to work with GraphQL. In today's demo, we will see how to get the Dynamic Component Presentation and reder the same in React based webapp. To start this I've created a new schema with Title and Description as content fields and used the default DXA standard Metadata Schema as well.

Based on this new schema I've created 3 new components and published them using Dynamic CT. They are now available via PCA.
3 DCPs for Demo Purpose

DCPs via GraphiQL

Next, is call PCA using Apollo Client and ReactJS and render the DCPs.

Here is the query to get all the DCPs to render them on the News and Article Landing page.
 const repoQuery = gql`  
  query  
 {  
  componentPresentations(namespaceId: 1, publicationId: 11, filter: {schema: {id: 789}}) {  
   edges {  
    cursor  
    node {  
     itemType  
     rawContent {  
      data  
     }  
    }  
   }  
  }  
 }  
 `  

Based on the query criteria we are getting 3 DCPs which is correct

PCA output

Next, Display the Data

Let's write some JSX to display the fetched data. I'm fetching/rendering the data from both Metadata and Content fields, just to test the feasibility/flexibility and syntax.

 class News extends Component {  
  render() {  
   console.log(this.props)  
   return (  
    <div>  
     <h2>News and Articles Landing Page</h2>   
     {  
      this.props.data.loading === true ? "Loading" :   
       this.props.data.componentPresentations.edges.map  
       (  
        data =>  
       <ul key={data.node.rawContent.data.Id}>  
       <li style={{fontWeight: 'bold'}}>  
         <a href={"newsdetails?ids="+data.node.rawContent.data.Id +  
          "&name="+data.node.rawContent.data.Content.title.replace(/[^a-zA-Z0-9]/g, '-')}>  
          {data.node.rawContent.data.Content.title}  
         </a>  
       </li>  
       <p>  
        {  
         data.node.rawContent.data.Metadata.metadata.description  
        }  
        </p>  
      </ul>  
       )  
     }  
    </div>  
   );  
  }  
 }  


And Finally, our News and Article Landing page with DCPs is ready, not the very attractive UI though 😊 

DCPs Rendering on ReactJS app
In the next blog, we will be creating News details page and will try to implement search and other features as well. 
You can download the sample application from GitHub, don't forget to update the PCA URL 

Happy Coding and Keep Sharing !!!! 

Saturday 6 April 2019

Hybrid Architecture SDL WEB 8.5 and SDL Tridion Sites 9

Well, In my previous post we saw how we can use GraphQL with SDL WEB 8.5 by simply installing Tridion Sites 9 Content Service that will work isolated and read data from 8.5 Broker. But, this has some limitations I saw some difference in the Broker Database of 8.5 and Tridion 9.e:g The "Component Presentation" table has a new column CONTENT_ID in the Tridion 9 Broker. This field is not there in the 8.5 Broker and this caused an issue while accessing Dynamic Component Presentations using GraphQL.

To, sort any such issues which we might face, we discussed the new Hybrid approach where we will have the Tridion 9 Broker and State Store Database with Tridion 9 Services Discovery, Deployer, and Content service running parallelly with 8.5 CMS .


High-Level Architecture Diagram

  1. Install Tridion 9 Broker and State_Store Database (As per the recommendation by SDL we need to install SQL Server 2016 SP2 or 2017).
  2. Update storage configuration as per the new Tridion 9 DB details in the Tridion 9 Discovery, Deployer and Content service(These services could be on the same box or in a new) and then install the services.
  3. After installation of service run the “java -jar discovery-registration.jar update” from discovery service config folder. This command will register the discovery service capabilities.
  4. The above steps/command will set up the services for the content delivery environment.
  5. Next is create a new topology manager in order to set the publishing
    1. We need to keep 8.5 and Tridion 9 broker DB in sync. So that we can run existing  8.5 and at the same time we should be able to query Tridion 9 Broker DB using GraphQL.
    2. We need targets that will publish to both the Brokers (e:g WEB8_Staging, Tridion9_Staging, WEB8_LIVE, and Tridion9_LIVE). This will keep the existing env. working and at the same time, we can use Graphql.
      • WEB8_Staging will point WEB 8 Staging Discovery 
      • Tridion9_Staging will point to Tridion 9 Staging Discovery
  6. There is another advantage here, so when you MIGRATE from CM 8.5 to Tridion 9 you already have your Broker DB up-to-date, content delivery microservices are already working.
The above setup will let you continue with the 8.5 and it will also give us the privilege to use GraphQL as well.


Happy Coding and Keep Sharing !!!

Monday 4 March 2019

SDL Tridion Sites 9 Content API GraphQL with SDL WEB 8.5

Recently, One of our customers requested this, can we have new SDL Tridion Sites 9 feature GraphQL in SDL WEB 8.5. They have the following questions before we can proceed to POC.

The client is very excited about this new GraphQL feature as this will bring lots of improvement in their existing implementation. So, they wanted to know can we have this new feature in 8.5.

  1. Can the CD side be upgraded to Sites 9 to have the GraphQL API, but the CM be left on Web 8.5?
  2. Can only the content microservice be updated to Sites 9 (while leaving the Broker and Deployer on 8.5) 
  3. Broker and Deployer also have to upgrade to 9?

We also need to think about downtown while we do all these. 

We did some investigation and come up with this idea/approach that we are not going to upgrade anything here just to have the new Content API feature (GraphQL).

So, We decided to Install only the Tridion Sites 9 Content Microservice and this will read the data from existing WEB 8.5 broker DB. NOTE:- We are still running the 8.5 services here no upgrade yet on CM or CD side.

With this approach, we were able to deliver what the client was requested from us. Now they are running their existing site using 8.5 content delivery and parallelly they started planning on building apps using 8.5 broker data using Tridion sites 9 GraphQL API. 

It was an interesting POC.

WEB 8.5 Content Service


Tridion Sites 9 Content Service running on same ENV and hitting 8.5 Broker to fetch the data.


Happy Coding and Keep Sharing !!!