Skip to content

Commit

Permalink
Only Package support for azure functions (#61)
Browse files Browse the repository at this point in the history
  • Loading branch information
sjuarezgx authored Sep 13, 2022
1 parent cbe1430 commit fcf7ebd
Show file tree
Hide file tree
Showing 8 changed files with 469 additions and 410 deletions.
6 changes: 6 additions & 0 deletions src/AzureFunctions/Definition.target
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
<DeploymentTarget>
<Id>AZURE_FUNCTIONS</Id>
<Name>Microsoft Azure Functions</Name>
<DeploymentScopes>
<Scope Id = "Backend" />
<Scope Id = "BackendToCloud" />
</DeploymentScopes>
<Version>1.0</Version>
<Description>Deploy to Azure Functions. Only main procedures or Rest services (including API Objects) can be selected.</Description>
<PackageTargets>azurefunctions.targets</PackageTargets>
<DeployMsbuild>deploy.msbuild</DeployMsbuild>
<DeployMsbuildTarget>Deploy</DeployMsbuildTarget>
<PackageMsbuild>createpackage.msbuild</PackageMsbuild>
<PackageMsbuildTarget>CreatePackage</PackageMsbuildTarget>
<ResolverFactory>GeneXus.Deployment.AzureFunctionsResolvers.ResolverFactory</ResolverFactory>
<Languages>
<!-- .Net Core -->
Expand Down
49 changes: 20 additions & 29 deletions src/AzureFunctions/azurefunctions.targets
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,30 @@
</PropertyGroup>
</Target>

<Target Name="ValidateDeployment" Inputs="@(Object)" Outputs="%(Object.Identity)" DependsOnTargets="Validate;ValidateRedisSupport">
<Target Name = "ValidatePackaging" DependsOnTargets = "Validate;ValidateRedisSupport">

<Error Text="Deployment does not include any REST Service (Expose As Rest Service = True)." Condition="$(AnyRestService)==false AND $(AZURE_FUNCTIONS_TRIGGER_TYPE) == 'http'"/>

<Error
Text="Azure functions deployment failed: Select only one main procedure."
Condition="'@(AllSelectedObjects->Count())' > 1 AND $(AZURE_FUNCTIONS_TRIGGER_TYPE) != 'http'" />


<Error
Text="Azure functions deployment failed: '%(Object.Identity)' is not Rest."
Condition="%(Object.IsRest) !='true' AND %(Object.Selected) == 'true' AND $(AZURE_FUNCTIONS_TRIGGER_TYPE) == 'http'" />

<Error
Text="Azure functions deployment failed: '%(Object.Identity)' is not a Procedure. Only procedures are supported unless Trigger Type is Http."
Condition="%(Object.Type) != 'Procedure' AND %(Object.Selected) == 'true' AND $(AZURE_FUNCTIONS_TRIGGER_TYPE) != 'http' " />

<Error
Text="Azure functions deployment failed: The Azure Function name cannot be empty."
Condition="$(AZURE_FUNCTIONS_FUNCTION_NAME) == '' AND $(AZURE_FUNCTIONS_TRIGGER_TYPE) != 'http'"/>

<Error
Text="Azure functions deployment failed: The Schedule time value cannot be empty"
Condition="'$(AZURE_FUNCTIONS_SCHEDULE_TIME_FORMAT)' == 'timevalue' AND '$(AZURE_FUNCTIONS_SCHEDULE_TIME)' == '' AND $(AZURE_FUNCTIONS_TRIGGER_TYPE) == 'Timer' " />

<Error
Text="Azure functions deployment failed: The App setting property name cannot be empty"
Condition="'$(AZURE_FUNCTIONS_SCHEDULE_TIME_FORMAT)' == 'appsettingvaluepair' AND '$(AZURE_FUNCTIONS_SCHEDULE_TIME_APPSETTINGNAME)' == '' AND $(AZURE_FUNCTIONS_TRIGGER_TYPE) == 'Timer'" />
Expand All @@ -63,14 +75,6 @@
Text="Azure functions deployment failed: The queue name cannot be empty"
Condition="'$(AZURE_FUNCTIONS_QUEUE_NAME)' == '' AND $(AZURE_FUNCTIONS_TRIGGER_TYPE) == 'Queue'" />

<Error
Text="Azure functions deployment failed: The queue connection cannot be empty"
Condition="'$(AZURE_FUNCTIONS_QUEUE_CONNECTION)' == '' AND $(AZURE_FUNCTIONS_TRIGGER_TYPE) == 'Queue'" />

<Error
Text="Azure functions deployment failed: The service bus connection cannot be empty"
Condition="'$(AZURE_FUNCTIONS_SERVICEBUS_CONNECTION)' == '' AND $(AZURE_FUNCTIONS_TRIGGER_TYPE) == 'servicebus'" />

<Error
Text="Azure functions deployment failed: The service bus queue name cannot be empty"
Condition="'$(AZURE_FUNCTIONS_SERVICEBUS_QUEUENAME)' == '' AND $(AZURE_FUNCTIONS_TRIGGER_TYPE) == 'servicebus' AND $(AZURE_FUNCTIONS_SERVICEBUS_TYPE) == 'queue'" />
Expand All @@ -82,28 +86,15 @@
<Error
Text="Azure functions deployment failed: The service bus subscription name cannot be empty"
Condition="'$(AZURE_FUNCTIONS_SERVICEBUS_SUBSCRIPTIONNAME)' == '' AND $(AZURE_FUNCTIONS_TRIGGER_TYPE) == 'servicebus' AND $(AZURE_FUNCTIONS_SERVICEBUS_TYPE) == 'topic'" />

<Error
Text="Azure functions deployment failed: '%(Object.Identity)' is not Rest."
Condition="%(Object.IsRest) !='true' AND %(Object.Selected) == 'true' AND $(AZURE_FUNCTIONS_TRIGGER_TYPE) == 'http'" />

<Error
Text="Azure functions deployment failed: '%(Object.Identity)' is not a Procedure. Only procedures are supported unless Trigger Type is Http."
Condition="%(Object.Type) != 'Procedure' AND %(Object.Selected) == 'true' AND $(AZURE_FUNCTIONS_TRIGGER_TYPE) != 'http' " />
<Error
Text="Azure functions deployment failed: The Azure Function name cannot be empty."
Condition="$(AZURE_FUNCTIONS_FUNCTION_NAME) == '' AND $(AZURE_FUNCTIONS_TRIGGER_TYPE) != 'http'"/>
<Error
Text="Azure functions deployment failed: The Azure settings cannot be empty."
Condition="$(AZURE_FUNCTIONS_FUNCTION_APP) == '' Or $(AZURE_FUNCTIONS_RESOURCE_GROUP) == ''" />

<Error
Text="Azure functions deployment failed: The Azure Identity settings must be complete."
Condition="$(AZURE_FUNCTIONS_SP_APP_ID) == '' Or $(AZURE_FUNCTIONS_SP_TENANT_ID) == '' Or $(AZURE_FUNCTIONS_SP_CREDENTIALS) == ''" />

Text="Azure functions deployment failed: The queue connection cannot be empty"
Condition="'$(AZURE_FUNCTIONS_QUEUE_CONNECTION)' == '' AND $(AZURE_FUNCTIONS_TRIGGER_TYPE) == 'Queue'" />
<Error
Text="Azure functions deployment failed: The APIM Version Set cannot be empty if the APIM API Version has a value."
Condition="$(AZURE_FUNCTIONS_TRIGGER_TYPE) == 'http' AND $(AZURE_APIM_API_VERSION_SET_ID) == '' AND $(AZURE_APIM_API_VERSION) != ''" />
Text="Azure functions deployment failed: The service bus connection cannot be empty"
Condition="'$(AZURE_FUNCTIONS_SERVICEBUS_CONNECTION)' == '' AND $(AZURE_FUNCTIONS_TRIGGER_TYPE) == 'servicebus'" />

</Target>

Expand Down
215 changes: 215 additions & 0 deletions src/AzureFunctions/createpackage.msbuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="CreatePackage" ToolsVersion="4.0">
<PropertyGroup>
<GXDeployFileProject>$([System.IO.Path]::GetFullPath('$(DeployFullPath)\..\..\..\..\web\$(ProjectName).gxdproj'))</GXDeployFileProject>
</PropertyGroup>
<Import Project="$(GX_PROGRAM_DIR)\GeneXus.AzureDeploy.targets"/>
<Import Project="$(GXDeployFileProject)"/>

<PropertyGroup Condition="'$(GENERATOR)' == '.NET Core' or '$(GENERATOR)' == '.NET'">
<UploadSource>$(DeployFullPath)</UploadSource>
<DeploymentTargetBinPath>$(GX_PROGRAM_DIR)\DeploymentTargets\AzureFunctions\AzFunctionFiles\bin</DeploymentTargetBinPath>
<DeploymentTargetAzfunctPath>$(GX_PROGRAM_DIR)\DeploymentTargets\AzureFunctions\AzFunctionFiles\bin\.azurefunctions</DeploymentTargetAzfunctPath>
<DeploymentTargetRuntimesPath>$(GX_PROGRAM_DIR)\DeploymentTargets\AzureFunctions\AzFunctionFiles\bin\runtimes</DeploymentTargetRuntimesPath>
</PropertyGroup>

<ItemGroup>
<AzureFunctionsRootDeps Include = "$(DeploymentTargetBinPath)\**\*.*" />
<AzureFunctionsFolderDeps Include = "$(DeploymentTargetAzfunctPath)\**\*.*" />
<AzureFunctionsRuntimesDeps Include = "$(DeploymentTargetRuntimesPath)\**\*.*" />

</ItemGroup>

<Target Name="CreatePackage" DependsOnTargets="ValidatePackaging;ZipDeploy" />

<Target Name="GenerateConfigs" DependsOnTargets = "OpenAPIGeneration">
<GenerateAzFunctionConfigs Condition="%(Object.Type) == 'Procedure' AND %(Object.selected) == 'true' AND $(AZURE_FUNCTIONS_TRIGGER_TYPE) != 'http'"

ObjectName="%(Object.Identity)"
ObjectQualifiedName ="%(Object.QualifiedName)"
FunctionName="$(AZURE_FUNCTIONS_FUNCTION_NAME)"
TriggerType="$(AZURE_FUNCTIONS_TRIGGER_TYPE)"
ScheduleTimeFormat="$(AZURE_FUNCTIONS_SCHEDULE_TIME_FORMAT)"
Schedule="$(AZURE_FUNCTIONS_SCHEDULE_TIME)"
ScheduleAppSettingName="$(AZURE_FUNCTIONS_SCHEDULE_TIME_APPSETTINGNAME)"
QueueName="$(AZURE_FUNCTIONS_QUEUE_NAME)"
QueueConnection="$(AZURE_FUNCTIONS_QUEUE_CONNECTION)"
ServiceBusType = "$(AZURE_FUNCTIONS_SERVICEBUS_TYPE)"
ServiceBusQueueName = "$(AZURE_FUNCTIONS_SERVICEBUS_QUEUENAME)"
ServiceBusTopicName = "$(AZURE_FUNCTIONS_SERVICEBUS_TOPICNAME)"
ServiceBusSubscName = "$(AZURE_FUNCTIONS_SERVICEBUS_SUBSCRIPTIONNAME)"
ServiceBusIsSessionEnabled = "$(AZURE_FUNCTIONS_SERVICEBUS_ISSESSIONENABLED)"
ServiceBusConnection = "$(AZURE_FUNCTIONS_SERVICEBUS_CONNECTION)"
DeployFullPath="$(DeployFullPath)" />

<ItemGroup>
<Procedure Include="@(Object)" Condition="'%(Object.Type)' == 'Procedure'" />
<API Include="@(Object)" Condition="'%(Object.Type)' == 'API'" />
<Transaction Include="@(Object)" Condition="'%(Object.Type)' == 'Transaction'" />
<DataProvider Include="@(Object)" Condition="'%(Object.Type)' == 'DataProvider'" />
<RestObject Include="@(Object)" Condition="%(Object.IsRest)=='true' AND %(Object.selected) == 'true'" />
</ItemGroup>

<PropertyGroup>
<APIRestSupport Condition="'@(API->'.')' != ''">true</APIRestSupport>
</PropertyGroup>

<GenerateAzFunctionConfigsHttp Condition="%(Object.selected) == 'true' AND %(Object.IsRest)=='true' AND $(AZURE_FUNCTIONS_TRIGGER_TYPE) == 'http'"

YamlFile = "$(OpenAPIDefinitionOutputFile)"
DeployFullPath="$(DeployFullPath)" />

<PropertyGroup>
<IntegratedSecurityEnabled Condition= "$(AZURE_FUNCTIONS_GAM_CONNECTION_KEY) != ''">true</IntegratedSecurityEnabled>
<IntegratedSecurityEnabled Condition= "$(AZURE_FUNCTIONS_GAM_CONNECTION_KEY) == ''">false</IntegratedSecurityEnabled>
</PropertyGroup>

<UpdateAzureFlagFile Condition="$(AZURE_FUNCTIONS_TRIGGER_TYPE) == 'http'"

AzureDeploy = "AzureHttpFunctions"
BaseServiceRoute = "$(AZURE_FUNCTIONS_ROUTE_PREFIX)"
IntegratedSecurityEnabled = "$(IntegratedSecurityEnabled)"
DeployFullPath = "$(DeployFullPath)" />

</Target>

<Target Name="PrepareDeploy" DependsOnTargets="GenerateConfigs;RedisSupport" >
<Message Text="Adding required files to the deploy...(this may take a while)" Importance="high"/>

<ItemGroup>
<ConfResources Include="$(DeployFullPath)\*.svc" />
<ConfResources Include="$(DeployFullPath)\Images.txt" Condition="Exists('$(DeployFullPath)\Images.txt')"/>
<ConfResources Include="$(DeployFullPath)\log.config" Condition="Exists('$(DeployFullPath)\log.config')"/>
<ConfResources Include="$(DeployFullPath)\log.console.config" Condition="Exists('$(DeployFullPath)\log.console.config')"/>
<ConfResources Include="$(DeployFullPath)\GeneXus.services" Condition ="Exists('$(DeployFullPath)\GeneXus.services')" />
<ConfResources Include="$(DeployFullPath)\gxazmappings.json" Condition ="$(AZURE_FUNCTIONS_TRIGGER_TYPE) != 'http'" />
<ConfResources Include="$(DeployFullPath)\functions.metadata" />
<ConfResources Include="$(DeployFullPath)\azureflag.json" Condition ="Exists('$(DeployFullPath)\azureflag.json')" />
<ConfResources Include="$(DeployFullPath)\appsettings.json" />
<ConfResources Include="$(DeployFullPath)\CloudServices.config" Condition ="Exists('$(DeployFullPath)\CloudServices.config')" />
</ItemGroup>

<ItemGroup>
<Modules Include="@(Object -> '%(Module)')" />
<ModuleDirs Include="%(Modules.Identity)" />
<ModuleRelativePath Include="@(ModuleDirs->Replace('.', '\'))" />
<ModuleRelPathLower Include="@(ModuleRelativePath->ToLower())" />
<ModuleFiles Include="$(DeployFullPath)\%(ModuleRelPathLower.Identity)\**\*.*" Condition="%(ModuleRelPathLower.Identity) != ''">
<RelativePath>%(ModuleRelPathLower.Identity)</RelativePath>
</ModuleFiles>
</ItemGroup>

<Copy SourceFiles="@(ModuleFiles)" DestinationFiles="@(ModuleFiles -> '$(DeployFullPath)\bin\%(RelativePath)\%(RecursiveDir)%(Filename)%(Extension)')" />

<ItemGroup>
<CacheMetadata Include="$(DeployFullPath)\Metadata\TableAccess\*.*" Condition="Exists('$(DeployFullPath)\Metadata\TableAccess')"/>
</ItemGroup>

<ItemGroup>
<PrivateDirectory Include="$(DeployFullPath)\private\*.*" Condition="Exists('$(DeployFullPath)\private')"/>
</ItemGroup>

<Copy SourceFiles="@(CacheMetadata)"
DestinationFiles="@(CacheMetadata -> '$(DeployFullPath)\bin\Metadata\TableAccess\%(Filename)%(Extension)')" SkipUnchangedFiles="true" />

<Copy SourceFiles="@(PrivateDirectory)"
DestinationFiles="@(PrivateDirectory -> '$(DeployFullPath)\bin\private\%(Filename)%(Extension)')" SkipUnchangedFiles="true" />

<Copy SourceFiles="@(AzureFunctionsRootDeps)"
DestinationFolder="$(DeployFullPath)\bin\%(RecursiveDir)" SkipUnchangedFiles="true"/>

<Copy SourceFiles="@(ConfResources)"
DestinationFiles="@(ConfResources -> '$(DeployFullPath)\bin\%(Filename)%(Extension)')" SkipUnchangedFiles="true" />

<UpdateHostFile Condition="$(AZURE_FUNCTIONS_TRIGGER_TYPE) == 'http'"

FunctionRoutePrefix = "$(AZURE_FUNCTIONS_ROUTE_PREFIX)"
DeployFullPath="$(DeployFullPath)" />

</Target>

<Target Name="ZipDeploy" DependsOnTargets = "PrepareDeploy" >
<CreateItem Include="$(DeployFullPath)\bin\**\*.*" >
<Output ItemName="ZipFiles" TaskParameter="Include"/>
</CreateItem>
<Zip ZipFileName="$(DeployFileFullPath)\$(ProjectName)_$(AZURE_FUNCTIONS_FUNCTION_NAME).zip" WorkingDirectory="$(DeployFullPath)\bin" Files="@(ZipFiles)" />
<Message Text="Application successfully Packaged to be uploaded to Azure : $(DeployFileFullPath)\$(ProjectName)_$(AZURE_FUNCTIONS_FUNCTION_NAME).zip" Importance="high"/>

</Target>

<Target Name="RedisSupport" Condition="$(AZURE_FUNCTIONS_TRIGGER_TYPE) == 'http' AND '$(AZURE_FUNCTIONS_SESSION_STATE_PROVIDER)' == 'Redis' AND '$(AZURE_FUNCTIONS_SESSION_PROVIDER_ADDRESS)' != ''">

<Message Text="Enabling Redis support" Importance="high"/>

<ItemGroup>
<RedisSessionTemplate Include="$(GX_PROGRAM_DIR)\DeploymentTargets\AzureFunctions\redis\$(GENERATOR)\*.*"/>
</ItemGroup>

<Copy SourceFiles="@(RedisSessionTemplate)" DestinationFolder="$(DeployFullPath)" Condition="'$(AZURE_FUNCTIONS_SESSION_STATE_PROVIDER)' == 'Redis'"/>

<ItemGroup>
<CSRedis Include="$(DeployFullPath)\CloudServices.redis.config"/>
</ItemGroup>

<CallTarget Targets="UpdateRedisCS" />

<XmlPeek XmlInputPath="@(CSRedis)" Query="Services/Service" Condition="Exists('@(CSRedis)')">
<Output TaskParameter="Result" ItemName="RedisService" />
</XmlPeek>

<ItemGroup>
<DestinationCS Include="$(DeployFullPath)\CloudServices.config"/>
<OriginalCS Include="$(DeployFullPath)\CloudServices.config"/>
</ItemGroup>

<PropertyGroup>
<CloudServiceExists Condition="Exists('@(OriginalCS)')">true</CloudServiceExists>
<CloudServiceExists Condition="!Exists('@(OriginalCS)')">false</CloudServiceExists>
</PropertyGroup>

<XmlPeek XmlInputPath="@(OriginalCS)" Query="Services/Service" Condition="'$(CloudServiceExists)' == 'true'">
<Output TaskParameter="Result" ItemName="OriginalServices" />
</XmlPeek>

</Target>

<Target Name="UpdateRedisCS" Condition="$(AZURE_FUNCTIONS_TRIGGER_TYPE) == 'http' AND '$(AZURE_FUNCTIONS_SESSION_STATE_PROVIDER)' == 'Redis' AND '$(AZURE_FUNCTIONS_SESSION_PROVIDER_ADDRESS)' != ''">

<XmlPoke
XmlInputPath="$(DeployFullPath)\CloudServices.redis.config"
Value="$(AZURE_FUNCTIONS_SESSION_PROVIDER_ADDRESS)"
Query="Services/Service/Properties/Property[Name='SESSION_PROVIDER_ADDRESS']/Value" />

<XmlPoke Condition = "$(AZURE_FUNCTIONS_SESSION_PROVIDER_PASSWORD) != ''"
XmlInputPath="$(DeployFullPath)\CloudServices.redis.config"
Value="$(AZURE_FUNCTIONS_SESSION_PROVIDER_PASSWORD)"
Query="Services/Service/Properties/Property[Name='SESSION_PROVIDER_PASSWORD']/Value" />

<XmlPoke Condition = "$(AZURE_FUNCTIONS_SESSION_PROVIDER_INSTANCE_NAME) != ''"
XmlInputPath="$(DeployFullPath)\CloudServices.redis.config"
Value="$(AZURE_FUNCTIONS_SESSION_PROVIDER_INSTANCE_NAME)"
Query="Services/Service/Properties/Property[Name='SESSION_PROVIDER_INSTANCE_NAME']/Value" />

<XmlPoke Condition = "$(AZURE_FUNCTIONS_SESSION_TIMEOUT) != ''"
XmlInputPath="$(DeployFullPath)\CloudServices.redis.config"
Value="$(AZURE_FUNCTIONS_SESSION_TIMEOUT)"
Query="Services/Service/Properties/Property[Name='SESSION_PROVIDER_SESSION_TIMEOUT']/Value" />
</Target>

<Target Name="AppendRedisCS" AfterTargets="RedisSupport" Condition="'@(RedisService->Count())' > 0">

<Message Text="Setting up new CloudServices.config" Importance="high"/>

<WriteLinesToFile File="@(DestinationCS)" Lines="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;" Overwrite="true" Encoding="UTF-8"/>

<WriteLinesToFile File="@(DestinationCS)" Lines="&lt;Services xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;" Overwrite="false"/>

<WriteLinesToFile File="@(DestinationCS)" Lines="@(OriginalServices)" Overwrite="false"/>

<WriteLinesToFile File="@(DestinationCS)" Lines="@(RedisService)" Overwrite="false"/>

<WriteLinesToFile File="@(DestinationCS)" Lines="&lt;/Services&gt;" Overwrite="false"/>

</Target>


</Project>
Loading

0 comments on commit fcf7ebd

Please sign in to comment.