/* ===== ProSkale Success Stories (scoped init, supports multiple blocks) ===== */ (function(){ // Shared data (edit these to your real case studies) const STORIES = [ { id:'fintech', title:'FinTech Platform Modernization', icon:'💰', color:'#0ea5e9', industry:'FinTech', img:'https://orpical.com/wp-content/uploads/2023/07/digital-transformation-in-banking.png', gradient:'radial-gradient(1200px 400px at 10% -10%, rgba(14,165,233,.20), transparent 60%), linear-gradient(135deg, rgba(14,165,233,.12), rgba(99,102,241,.12))', lead:'Legacy monolith with poor UX, slow deployments, and scalability bottlenecks.', solution:[ 'Split monolith to microservices with API gateway', 'React/Next.js front-end with design tokens', 'CI/CD with canary releases and automated QA', 'Observability via OpenTelemetry + Grafana' ], results:['70% faster loads','3× engagement','99.99% uptime','Zero-downtime releases'], stats:{a:'70%',aText:'faster page loads',b:'3×',bText:'increase in engagement'} }, { id:'commerce', title:'E-Commerce PWA Development', icon:'🛍️', color:'#f97316', industry:'E-Commerce', img:'https://img.freepik.com/premium-photo/ecommerce-business-concept_204719-89016.jpg?w=740&q=80', gradient:'radial-gradient(1200px 400px at 0% -10%, rgba(249,115,22,.18), transparent 60%), linear-gradient(135deg, rgba(251,146,60,.12), rgba(236,72,153,.12))', lead:'Mobile-first, offline-capable shopping with lightning performance.', solution:[ 'PWA with Vue 3 + Nuxt, edge caching', 'Headless cart & checkout', 'Image/CDN optimization and code splitting', 'A/B testing pipeline for features' ], results:['+40% mobile conversions','60% faster pages','Offline experience','SEO boost (SSR)'], stats:{a:'+40%',aText:'mobile conversion lift',b:'60%',bText:'faster LCP'} }, { id:'health', title:'Healthcare SaaS Collaboration', icon:'🏥', color:'#10b981', industry:'Healthcare', img:'https://kms-healthcare.com/wp-content/uploads/2023/09/agile-software-development-in-healthcare-2-1024x575.png', gradient:'radial-gradient(1200px 400px at 10% -10%, rgba(16,185,129,.18), transparent 60%), linear-gradient(135deg, rgba(16,185,129,.12), rgba(59,130,246,.12))', lead:'HIPAA-compliant, real-time collaboration app with strict latency targets.', solution:[ 'React + TypeScript + WebRTC for video', 'FastAPI microservices on Azure AKS', 'End-to-end encryption & audit trails', 'Autoscaling with HPA & queues' ], results:['HIPAA compliant','50ms avg latency','10k+ concurrent users','Secure audit logs'], stats:{a:'50ms',aText:'average latency',b:'10k+',bText:'concurrent users'} } ]; // Initialize each block on the page document.querySelectorAll('.ps-stories').forEach((root) => { const $ = (s, el=root) => el.querySelector(s); const $$ = (s, el=root) => Array.from(el.querySelectorAll(s)); const INDUSTRIES = ['All', ...Array.from(new Set(STORIES.map(s=>s.industry)))]; const storyFilters = $('#storyFilters'); const rail = $('#storiesRail'); const dotsWrap = $('#storiesDots'); const btnPrev = $('#storiesPrev'); const btnNext = $('#storiesNext'); const sModal = $('#storyModal'); const sClose = $('#storyClose'); const sIcon = $('#storyIcon'); const sTitle = $('#storyTitle'); const sIndustry = $('#storyIndustry'); const sLead = $('#storyLead'); const sSol = $('#storySolution'); const sRes = $('#storyResults'); const sStatA = $('#storyStatA'); const sStatAT= $('#storyStatAText'); const sStatB = $('#storyStatB'); const sStatBT= $('#storyStatBText'); const sDots = $('#storyDots'); const sPrev = $('#storyPrev'); const sNext = $('#storyNext'); let activeFilter='All', visible=STORIES.slice(), activeIndex=0, modalIndex=0; // Filters storyFilters.innerHTML = INDUSTRIES .map(n=>``) .join(''); storyFilters.addEventListener('click', (e)=>{ const b=e.target.closest('.filter-chip'); if(!b) return; activeFilter=b.dataset.name; $$('.filter-chip', storyFilters).forEach(x=>x.classList.toggle('active', x===b)); renderStories(); }); // Card template function card(s,i){ return `
${s.title}
${s.title}
${s.industry}
${(s.results||[]).slice(0,3).map(b=>`${b}`).join('')}
${s.stats.a}${s.stats.aText}
${s.stats.b}${s.stats.bText}
`; } function renderStories(){ visible = STORIES.filter(s => activeFilter === 'All' || s.industry === activeFilter); rail.innerHTML = visible.map((s,i)=>card(s,i)).join(''); $$('.story-card', rail).forEach(c => c.addEventListener('click', () => openModal(+c.dataset.index))); activeIndex = 0; renderDots(); scrollTo(0, false); } function renderDots(){ dotsWrap.innerHTML = visible.map((_,i)=>``).join(''); $$('.car-dot', dotsWrap).forEach(d => d.addEventListener('click', () => scrollTo(+d.dataset.i))); } function scrollTo(i, smooth=true){ activeIndex = Math.max(0, Math.min(i, visible.length - 1)); const card = rail.children[activeIndex]; if (!card) return; const left = card.offsetLeft - (rail.clientWidth - card.clientWidth)/2; rail.scrollTo({ left, behavior: smooth ? 'smooth' : 'auto' }); renderDots(); } btnPrev.addEventListener('click', () => scrollTo(activeIndex - 1)); btnNext.addEventListener('click', () => scrollTo(activeIndex + 1)); rail.addEventListener('keydown', e => { if (e.key === 'ArrowRight') scrollTo(activeIndex + 1); if (e.key === 'ArrowLeft') scrollTo(activeIndex - 1); }); // Modal function openModal(i){ modalIndex = i; fillModal(); sModal.classList.add('show'); sModal.setAttribute('aria-hidden','false'); document.body.style.overflow = 'hidden'; } function closeModal(){ sModal.classList.remove('show'); sModal.setAttribute('aria-hidden','true'); document.body.style.overflow = ''; } function fillModal(){ const s = visible[modalIndex]; if (!s) return; sIcon.textContent = s.icon; sTitle.textContent = s.title; sIndustry.textContent = s.industry; sLead.textContent = s.lead; sSol.innerHTML = s.solution.map(x=>`
  • ${x}
  • `).join(''); sRes.innerHTML = s.results.map(x=>`${x}`).join(''); sStatA.textContent = s.stats.a; sStatAT.textContent = s.stats.aText; sStatB.textContent = s.stats.b; sStatBT.textContent = s.stats.bText; sDots.innerHTML = visible.map((_,i)=>``).join(''); $$('.car-dot', sDots).forEach(d => d.addEventListener('click', () => { modalIndex = +d.dataset.i; fillModal(); })); } $('#storyClose').addEventListener('click', closeModal); sModal.addEventListener('click', e => { if (e.target === sModal) closeModal(); }); $('#storyPrev').addEventListener('click', () => { modalIndex = (modalIndex - 1 + visible.length) % visible.length; fillModal(); }); $('#storyNext').addEventListener('click', () => { modalIndex = (modalIndex + 1) % visible.length; fillModal(); }); document.addEventListener('keydown', e => { if (sModal.classList.contains('show') && e.key === 'Escape') closeModal(); }); // Init renderStories(); }); })(); function showTab(evt, tabId) { const tabs = document.querySelectorAll(".tab-content"); const buttons = document.querySelectorAll(".tablink"); tabs.forEach(tab => tab.classList.remove("active")); buttons.forEach(btn => btn.classList.remove("active")); document.getElementById(tabId).classList.add("active"); evt.currentTarget.classList.add("active"); } (() => { const STORIES = [ {id:'fintech',title:'FinTech Platform Modernization',icon:'💰',color:'#0ea5e9',industry:'FinTech',img:'https://orpical.com/wp-content/uploads/2023/07/digital-transformation-in-banking.png',gradient:'radial-gradient(1200px 400px at 10% -10%, rgba(14,165,233,.20), transparent 60%), linear-gradient(135deg, rgba(14,165,233,.12), rgba(99,102,241,.12))',lead:'Legacy monolith with poor UX, slow deployments, and scalability bottlenecks.',solution:['Split monolith to microservices with API gateway','React/Next.js front-end with design tokens','CI/CD with canary releases and automated QA','Observability via OpenTelemetry + Grafana'],results:['70% faster loads','3× engagement','99.99% uptime','Zero-downtime releases'],stats:{a:'70%',aText:'faster page loads',b:'3×',bText:'increase in engagement'}}, {id:'commerce',title:'E-Commerce PWA Development',icon:'🛍️',color:'#f97316',industry:'E-Commerce',img:'https://img.freepik.com/premium-photo/ecommerce-business-concept_204719-89016.jpg?w=740&q=80',gradient:'radial-gradient(1200px 400px at 0% -10%, rgba(249,115,22,.18), transparent 60%), linear-gradient(135deg, rgba(251,146,60,.12), rgba(236,72,153,.12))',lead:'Mobile-first, offline-capable shopping with lightning performance.',solution:['PWA with Vue 3 + Nuxt, edge caching','Headless cart & checkout','Image/CDN optimization and code splitting','A/B testing pipeline for features'],results:['+40% mobile conversions','60% faster pages','Offline experience','SEO boost (SSR)'],stats:{a:'+40%',aText:'mobile conversion lift',b:'60%',bText:'faster LCP'}}, {id:'health',title:'Healthcare SaaS Collaboration',icon:'🏥',color:'#10b981',industry:'Healthcare',img:'https://kms-healthcare.com/wp-content/uploads/2023/09/agile-software-development-in-healthcare-2-1024x575.png',gradient:'radial-gradient(1200px 400px at 10% -10%, rgba(16,185,129,.18), transparent 60%), linear-gradient(135deg, rgba(16,185,129,.12), rgba(59,130,246,.12))',lead:'HIPAA-compliant, real-time collaboration app with strict latency targets.',solution:['React + TypeScript + WebRTC for video','FastAPI microservices on Azure AKS','End-to-end encryption & audit trails','Autoscaling with HPA & queues'],results:['HIPAA compliant','50ms avg latency','10k+ concurrent users','Secure audit logs'],stats:{a:'50ms',aText:'average latency',b:'10k+',bText:'concurrent users'}} ]; const INDUSTRIES = ['All', ...Array.from(new Set(STORIES.map(s=>s.industry)))]; const storyFilters = $('#storyFilters'); const rail = $('#storiesRail'); const dotsWrap = $('#storiesDots'); const btnPrev = $('#storiesPrev'); const btnNext = $('#storiesNext'); let activeFilter='All', visible=STORIES.slice(), activeIndex=0; storyFilters.innerHTML = INDUSTRIES.map(n=>``).join(''); storyFilters.addEventListener('click', e=>{ const b=e.target.closest('.filter-chip'); if(!b) return; activeFilter=b.dataset.name; $$('.filter-chip', storyFilters).forEach(x=>x.classList.toggle('active', x===b)); renderStories(); }); function card(s,i){ return `
    ${s.title}
    ${s.title}
    ${s.industry}
    ${(s.results||[]).slice(0,3).map(b=>`${b}`).join('')}
    ${s.stats.a}${s.stats.aText}
    ${s.stats.b}${s.stats.bText}
    `; } function renderStories(){ visible = STORIES.filter(s=>activeFilter==='All' || s.industry===activeFilter); rail.innerHTML = visible.map((s,i)=>card(s,i)).join(''); $$('.story-card', rail).forEach(c=>c.addEventListener('click',()=>openModal(+c.dataset.index))); activeIndex = 0; renderDots(); scrollTo(0,false); } function renderDots(){ dotsWrap.innerHTML = visible.map((_,i)=>``).join(''); $$('.car-dot', dotsWrap).forEach(d=>d.addEventListener('click',()=>scrollTo(+d.dataset.i))); } function scrollTo(i, smooth=true){ activeIndex=Math.max(0,Math.min(i,visible.length-1)); const card = rail.children[activeIndex]; if(!card) return; const left = card.offsetLeft - (rail.clientWidth - card.clientWidth)/2; rail.scrollTo({left,behavior:smooth?'smooth':'auto'}); renderDots(); } btnPrev.addEventListener('click', ()=>scrollTo(activeIndex-1)); btnNext.addEventListener('click', ()=>scrollTo(activeIndex+1)); rail.addEventListener('keydown', e=>{ if(e.key==='ArrowRight')scrollTo(activeIndex+1); if(e.key==='ArrowLeft')scrollTo(activeIndex-1); }); /* modal */ const sModal=$('#storyModal'); const sClose=$('#storyClose'); const sIcon=$('#storyIcon'); const sTitle=$('#storyTitle'); const sIndustry=$('#storyIndustry'); const sLead=$('#storyLead'); const sSol=$('#storySolution'); const sRes=$('#storyResults'); const sStatA=$('#storyStatA'); const sStatAT=$('#storyStatAText'); const sStatB=$('#storyStatB'); const sStatBT=$('#storyStatBText'); const sDots=$('#storyDots'); const sPrev=$('#storyPrev'); const sNext=$('#storyNext'); let modalIndex=0; function openModal(i){ modalIndex=i; fill(); sModal.classList.add('show'); sModal.setAttribute('aria-hidden','false'); document.body.style.overflow='hidden'; } function closeModal(){ sModal.classList.remove('show'); sModal.setAttribute('aria-hidden','true'); document.body.style.overflow=''; } function fill(){ const s=visible[modalIndex]; if(!s) return; sIcon.textContent=s.icon; sTitle.textContent=s.title; sIndustry.textContent=s.industry; sLead.textContent=s.lead; sSol.innerHTML=s.solution.map(x=>`
  • ${x}
  • `).join(''); sRes.innerHTML=s.results.map(x=>`${x}`).join(''); sStatA.textContent=s.stats.a; sStatAT.textContent=s.stats.aText; sStatB.textContent=s.stats.b; sStatBT.textContent=s.stats.bText; sDots.innerHTML=visible.map((_,i)=>``).join(''); $$('.car-dot', sDots).forEach(d=>d.addEventListener('click',()=>{modalIndex=+d.dataset.i; fill();})); } sClose.addEventListener('click',closeModal); sModal.addEventListener('click',e=>{ if(e.target===sModal) closeModal(); }); sPrev.addEventListener('click',()=>{ modalIndex=(modalIndex-1+visible.length)%visible.length; fill(); }); sNext.addEventListener('click',()=>{ modalIndex=(modalIndex+1)%visible.length; fill(); }); document.addEventListener('keydown',e=>{ if(!sModal.classList.contains('show')) return; if(e.key==='Escape') closeModal(); }); renderStories(); })(); Skip to main content

    Azure Data Factory (ADF) is a cloud-based ETL and data integration service that allows users to create data-driven workflows for orchestrating both data movement and data transformation.

    • It is used to create and schedule data-driven workflows (called pipelines) that can ingest and transform data from disparate data stores.
    • ADF can also publish transformed data to data stores such as Azure Synapse Analytics for business intelligence.
    • It is a code-free ETL as a service on Azure.

    ADF’s are built using Azure Resource Manager (ARM) templates, a decorative syntax that can create and deploy an entire Azure infrastructure. This allows for the intention of deployment to be stated, without having to write the programming commands, allowing ease when deploying to one or multiple resources like virtual machines and storage systems. 

    • It allows for repeatability, meaning you can deploy the same template multiple times with consistent results. 
    • ARM orchestrates the order of deployment for resources to ensure they are created in the correct order. 
    • You can deploy any Azure resource though the ARM template. 
    • There is built in validation ensuring success, and limiting the likelihood of unsuccessful deployment. 

    Following functions can be performed by Azure Data Factory:

    Ingest – Data pipelines are used to move data from both on-premise and cloud sources to destination location.

    Transform – The transform functionality of ADF is used to transform data. Data Flows are created to build data transformation graphs that are executed on Spark by ADF.

    Publish – ADF can write transformed data in business-ready consumable form to destinations such as Azure Data Warehouse, Azure SQL Database, Azure Cosmos DB, and several others.

    Monitoring – Monitoring can be performed on ADF console while pipelines are being executed.

     

    Components of ADF

    • Pipelines – A pipeline is a logical grouping of activities that together perform a task.
      • The activities in a pipeline define actions to perform on data.
      • An Azure Data Factory or Synapse workspace can have one or more pipelines.
    • Activities – Activities represent a processing step in a pipeline
    • Datasets – Datasets represent data structures within the data stores, which simply point to or reference the data you want to use in your activities as inputs or outputs.
    • Linked services – Linked services are much like connection strings, which define the connection information that’s needed for Data Factory to connect to external resources. Linked services are used for two purposes in Data Factory:
      • To represent a data store that includes, but isn’t limited to, a SQL Server database
      • To represent a compute resource that can host the execution of an activity.
    • Data Flows – Represent data lineage.
    • Integration Runtime – A linked service defines a target data store or a compute service. An integration runtime provides the bridge between the activity and linked Services.
    • Triggers – Triggers represent the unit of processing that determines when a pipeline execution needs to be kicked off.
    • Pipeline Runs – A pipeline run is an instance of the pipeline execution.
    • Parameters – Parameters are key-value pairs of read-only configuration.  Parameters are defined in the pipeline.
    • Control Flow – Control flow is an orchestration of pipeline activities that includes chaining activities in a sequence, branching, defining parameters at the pipeline level, and passing arguments while invoking the pipeline on-demand or from a trigger.
    • Variables – Variables can be used inside of pipelines to store temporary values and can also be used in conjunction with parameters to enable passing values between pipelines, data flows, and other activities.

    Automation of ADF Pipeline Creation using Azure Resource Manager (ARM)

    What is ARM – It is used to implement infrastructure as code for deploying Azure resources. Deployment is done through ARM Templates, a JSON file that defines infrastructure components and configurations.

    Steps for Deploying ADH using ARM Template:

    • Identify and document source and target data locations.
    • Define infrastructure resources and configurations in a ARM template.
    • Include the following resources in the template:
      a. Data Storage account
      b. Azure Data Factory
      c. Data Factory Linked Services
      d. Data sets
      e. Pipelines
    • Deploy the template.
    • Submit the template for execution and every successful completion.
    • Verify that all resources are created.
    • Create a Trigger for starting the Pipeline.
    • Monitor.
    • Verify the output file.

    Summary

    Azure Data Factory (ADF) is a SaaS resource from Azure. It is easy to use and can be used for data sources located both on-premise and cloud environments.

     

     

    From narrow automation solutions for migrations and cost monitoring, to delivering an entire Modern Data Platform in Azure, see how we can partner for immediate ROI.

    Leave a Reply