Core/Solr-Module.psm1

$ErrorActionPreference = "Stop"

function DownloadSolr {
    [CmdletBinding()]
    Param
    (
        [string]$Version,
        [string]$InstallDir
    )
   
    Write-Output "Solr download started..."

    if (Test-Path $InstallDir) {
        Remove-Item "$InstallDir" -Recurse -Force | Out-Null
    }
    New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null

    $downloadFolder = "~\Downloads"
    $solrPackage = "https://archive.apache.org/dist/lucene/solr/$Version/solr-$Version.zip"
    $solrZip = "$downloadFolder\SolrTemp.zip"
    DownloadAndUnzip -ToolName "Solr" -DownloadFullPath $solrZip -DownloadURL $solrPackage -TargetDir (Split-Path -Path $InstallDir)
    
    Write-Output "Solr download done."
}

function RunSolrAsService {
    [CmdletBinding()]
    Param
    (
        [string]$ServiceDir,
        [string]$ServiceName,
        [int]$Port,
        [string]$ServiceDisplayName,
        [string]$ServiceDescription
    )

    Write-Output "Running Solr as a service..."

    NewWindowsService -Service $ServiceName -Directory $ServiceDir -Port $Port -DisplayName $ServiceDisplayName -Description $ServiceDescription
    StartWindowsService -Service $ServiceName
    
    Write-Output "Running Solr as a service done."
}

function ConfigureSolr {
    [CmdletBinding()]
    Param
    (
        [string]$Version,
        [string]$InstallDir,
        [string]$HostName,
        [string]$SSLCert,
        [string]$ServiceName
    )
   
    Write-Output "Solr configuration started..."

    $JREPath = Get-ChildItem -Directory "C:\Program Files\Java" |  Sort-Object CreationTime -Descending | Select-Object -ExpandProperty FullName -First 1
    $jreVal = [Environment]::GetEnvironmentVariable("JAVA_HOME", [EnvironmentVariableTarget]::Machine)
    if ($jreVal -ne $JREPath) {
        Write-Output "Setting JAVA_HOME environment variable..."
        [Environment]::SetEnvironmentVariable("JAVA_HOME", $JREPath, [EnvironmentVariableTarget]::Machine)
    }

    DownloadSolr -Version $Version -InstallDir $InstallDir

    if ($HostName -ne "localhost") {
        AddHostFileEntry -IP "127.0.0.1" -HostName $HostName
    }

    if (!(Test-Path -Path "$InstallDir\server\etc\solr-ssl.keystore.pfx")) {
        Write-Output "Exporting SSL Certificate for Solr to use..."

        if (!(IsCertInstalled -Cert $SSLCert)) {
            Write-Error "SSL Cert '$SSLCert' not found..."
        }

        $cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object FriendlyName -eq $SSLCert
        $certStore = "$InstallDir\server\etc\solr-ssl.keystore.pfx"
        $certPwd = ConvertTo-SecureString -String "secret" -Force -AsPlainText
        $cert | Export-PfxCertificate -FilePath $certStore -Password $certpwd | Out-Null
    }

    # Update solr cfg to use keystore & right host name
    if (!(Test-Path -Path "$InstallDir\bin\solr.in.cmd.old")) {
        Write-Output "Rewriting solr config..."

        $cfg = Get-Content "$InstallDir\bin\solr.in.cmd"
        Rename-Item "$InstallDir\bin\solr.in.cmd" "$InstallDir\bin\solr.in.cmd.old"
        $newCfg = $cfg | ForEach-Object { $_ -replace "REM set SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.jks", "set SOLR_SSL_KEY_STORE=$certStore" }
        $newCfg = $newCfg | ForEach-Object { $_ -replace "REM set SOLR_SSL_KEY_STORE_PASSWORD=secret", "set SOLR_SSL_KEY_STORE_PASSWORD=secret" }
        $newCfg = $newCfg | ForEach-Object { $_ -replace "REM set SOLR_SSL_TRUST_STORE=etc/solr-ssl.keystore.jks", "set SOLR_SSL_TRUST_STORE=$certStore" }
        $newCfg = $newCfg | ForEach-Object { $_ -replace "REM set SOLR_SSL_TRUST_STORE_PASSWORD=secret", "set SOLR_SSL_TRUST_STORE_PASSWORD=secret" }
        $newCfg = $newCfg | ForEach-Object { $_ -replace "REM set SOLR_HOST=192.168.1.1", "set SOLR_HOST=$HostName" }
        $newCfg | Set-Content "$InstallDir\bin\solr.in.cmd"
    }
    
    Write-Output "Solr configuration done."
}

function GetSolrPipelinesFile {
    $version = $SAFConfiguration.sitecore.version
    $majorMinorOnly = $version.Substring(0, ($version.LastIndexOf('.')))
    return "$SAFInstallSolrPipelines\$majorMinorOnly\Pipelines.json"
}

function InstallSolr {
    [CmdletBinding()]
    Param
    (
        [switch]$Force
    )
    
    RunPipeline -DefinitionFile (GetSolrPipelinesFile) -Name "installOnPremSolr" -Force:$Force
}

function GenerateNewSolrConfigSets {
    [CmdletBinding()]
    Param
    (
        [switch]$Force
    )
    
    RunPipeline -DefinitionFile (GetSolrPipelinesFile) -Name "generateSolrConfigSets" -Force:$Force
}

function CreateNewSolrCoresViaHTTP {
    [CmdletBinding()]
    Param
    (
        [switch]$Force
    )
    
    RunPipeline -DefinitionFile (GetSolrPipelinesFile) -Name "createSolrCoresViaHTTP" -Force:$Force
}

function CreateNewSolrCoreViaHTTP {
    [CmdletBinding()]
    Param
    (
        [string]$SolrUrl,
        [string]$CoreName
    )

    $solrParams = @{
        Path       = "$PSScriptRoot\custom-solrHTTP.json"
        SolrUrl    = $SolrUrl
        CoreName   = $CoreName
    }
    Install-SitecoreConfiguration @solrParams
}

function DuplicateConfigSet {
    [CmdletBinding()]
    Param
    (
        [string]$SolrRootDir,
        [string]$OriginalCoreName
    )

    Write-Output "Duplicating '$OriginalCoreName' configset..."

    $originalCoreDir = "$SolrRootDir\server\solr\$OriginalCoreName"
    if (!(Test-Path "$originalCoreDir")) {
        throw "SAF can not create secondary core for '$originalCoreDir' because it doesn't exist."
    }
    $secondaryCoreName = "$($OriginalCoreName)_sec"
    $secondaryCoreDir = "$SolrRootDir\server\solr\$secondaryCoreName"
    if (Test-Path "$secondaryCoreDir") {
        Remove-Item "$secondaryCoreDir" -Recurse -Force | Out-Null
    }
    Copy-Item "$originalCoreDir" -Destination "$secondaryCoreDir" -Force -Recurse | Out-Null
    if (Test-Path "$secondaryCoreDir\core.properties") {
        ReplaceStringInFile -FilePath "$secondaryCoreDir\core.properties" -OldValue "$OriginalCoreName" -NewValue "$secondaryCoreName"
    }
    Write-Output "Done."
}

function AddSolrRebuildCoresConfig {
    [CmdletBinding()]
    Param
    (
        [string]$SitecoreDir,
        [PSCustomObject[]]$RebuildCores
    )

    Write-Output "Adding 'Solr.RebuildCores.config' to 'App_Config\Environment'..."
    
    $envConfigDir = "$SitecoreDir\App_Config\Environment"
    if(!(Test-Path "$envConfigDir")){
        throw "'$envConfigDir' doesn't exist..."
    }

    $xmlIndexNode = Get-Content -Path "$PSScriptRoot\ConfigTemplates\Solr.RebuildCores.IndexNode.xml" -Raw

    $xmlIndexesNodes = ""
    foreach ($core in $RebuildCores) {
        $xmlIndexesNodes += $xmlIndexNode
        $xmlIndexesNodes = $xmlIndexesNodes -Replace "{{indexname}}", $core.indexName
        $xmlIndexesNodes = $xmlIndexesNodes -Replace "{{corename}}", $core.mainName
    }

    $configTemplate = Get-Content -Path "$PSScriptRoot\ConfigTemplates\Solr.RebuildCores.config" -Raw
    $configValue = $configTemplate -Replace "{{indexes}}", $xmlIndexesNodes
    $formattedValue = FormatAsXML -Text $configValue
    Set-Content -Path "$envConfigDir\Solr.RebuildCores.config" -Value $formattedValue -Encoding "UTF8" -Force

    Write-Output "Done."
}

Export-ModuleMember -Function "InstallSolr"
Export-ModuleMember -Function "GenerateNewSolrConfigSets"
Export-ModuleMember -Function "CreateNewSolrCoresViaHTTP"
Export-ModuleMember -Function "ConfigureSolr"
Export-ModuleMember -Function "DownloadSolr"
Export-ModuleMember -Function "RunSolrAsService"
Export-ModuleMember -Function "DuplicateConfigSet"
Export-ModuleMember -Function "AddSolrRebuildCoresConfig"
Export-ModuleMember -Function "CreateNewSolrCoreViaHTTP"