/** * Creates a Function and waits for the it to become available to use. * * @param fnManagementClient the service client to use to create the Application. * @param applicationId the OCID of the Application which owns the Function. * @param displayName the display name of created Function. * @param image an accessible OCI Registry image implementing the function to be executed. * @param memoryInMBs the maximum amount of memory available (128, 256, 512, 1024) to the function in MB. * @param timeoutInSeconds the maximum amount of time a function can execute (30 - 120) in seconds. * @return the created Function. */ private static async Task <Function> CreateFunction(FunctionsManagementClient fnManagementClient, string applicationId, string image, long memoryInMBs, int timeoutInSeconds) { logger.Info("Creating function"); // Create a new function var createFunctionDetails = new CreateFunctionDetails { ApplicationId = applicationId, DisplayName = FunctionName, Image = image, MemoryInMBs = memoryInMBs, TimeoutInSeconds = timeoutInSeconds }; var createFunctionRequest = new CreateFunctionRequest { CreateFunctionDetails = createFunctionDetails }; var createFunctionResponse = await fnManagementClient.CreateFunction(createFunctionRequest); logger.Info("Waiting for Function to be in Active state"); var getFunctionRequest = new GetFunctionRequest { FunctionId = createFunctionResponse.Function.Id }; var getFunctionResponse = fnManagementClient.Waiters.ForFunction(getFunctionRequest, Function.LifecycleStateEnum.Active).Execute(); logger.Info($"Function: {FunctionName} is Active"); return(getFunctionResponse.Function); }
protected override void ProcessRecord() { base.ProcessRecord(); client?.Dispose(); client = new FunctionsManagementClient(AuthProvider, new Oci.Common.ClientConfiguration { RetryConfiguration = retryConfig, TimeoutMillis = TimeOutInMillis, ClientUserAgent = PSUserAgent }); try { string region = GetPreferredRegion(); if (region != null) { WriteDebug("Choosing Region:" + region); client.SetRegion(region); } if (Endpoint != null) { WriteDebug("Choosing Endpoint:" + Endpoint); client.SetEndpoint(Endpoint); } } catch (Exception ex) { TerminatingErrorDuringExecution(ex); } }
/** * Creates an Application and waits for it to become available to use. * * @param fnManagementClient the service client to use to create the application. * @param compartmentId the OCID of the compartment which owns the Application. * @param displayName the display name of the created Application. * @param subnetIds a List of subnets (in different ADs) that will expose the function. * @return the created application. */ private static async Task <Application> CreateApplication(FunctionsManagementClient fnManagementClient, string compartmentId, List <string> subnetIds) { logger.Info("Creating application"); // Create a new Application var createApplicationDetails = new CreateApplicationDetails { CompartmentId = compartmentId, DisplayName = AppName, SubnetIds = subnetIds }; var createApplicationRequest = new CreateApplicationRequest { CreateApplicationDetails = createApplicationDetails }; var createApplicationResponse = await fnManagementClient.CreateApplication(createApplicationRequest); logger.Info("Waiting for application to become Active"); var getApplicationRequest = new GetApplicationRequest { ApplicationId = createApplicationResponse.Application.Id }; var getApplicationResponse = fnManagementClient.Waiters.ForApplication(getApplicationRequest, Application.LifecycleStateEnum.Active).Execute(); logger.Info($"Application: {getApplicationResponse.Application.DisplayName} is Active"); return(getApplicationResponse.Application); }
/** * Invoke a function. * * @param provider the OCI credentials provider. * @param compartmentId the compartment in which to created the required * resources. * @param payload the payload to be sent to the function on invocation. */ private static async Task InvokeFunction(IBasicAuthenticationDetailsProvider provider, string compartmentId, string payload) { var fnManagementClient = new FunctionsManagementClient(provider); var fnInvokeClient = new FunctionsInvokeClient(provider); try { // Invoke the function var fn = await GetUniqueFunctionByName(fnManagementClient, compartmentId); var response = await InvokeFunction(fnInvokeClient, fn, payload); if (response != null) { logger.Info($"Response from function: {response}"); } } catch (Exception e) { logger.Error($"Failed to invoke function: {e}"); } finally { fnInvokeClient.Dispose(); fnManagementClient.Dispose(); } }
/** * Remove all resources created by the 'setup' operation. * * NB: Resources can only be removed 30 minutes after the last Function * invocation. * * @param provider the OCI credentials provider. * @param region the OCI region in which to create the required * resources. * @param compartmentId the compartment in which to created the required * resources. * @param name a name prefix to easily identify the resources. */ private static async Task TearDownResources(IBasicAuthenticationDetailsProvider provider, string compartmentId) { var identityClient = new IdentityClient(provider); var vcnClient = new VirtualNetworkClient(provider); var fnManagementClient = new FunctionsManagementClient(provider); try { logger.Info("Cleaning up...."); var vcn = await GetUniqueVcnByName(vcnClient, compartmentId); var ig = await GetUniqueInternetGatewayByName(vcnClient, compartmentId, vcn.Id); var rt = await GetUniqueRouteTableByName(vcnClient, compartmentId, vcn.Id); var subnet = await GetUniqueSubnetByName(vcnClient, compartmentId, vcn.Id); var application = await GetUniqueApplicationByName(fnManagementClient, compartmentId); var fn = await GetUniqueFunctionByName(fnManagementClient, application.Id, FunctionName); if (fn != null) { await DeleteFunction(fnManagementClient, fn.Id); } if (application != null) { await DeleteApplication(fnManagementClient, application.Id); } if (ig != null) { await ClearRouteRulesFromDefaultRouteTable(vcnClient, vcn.DefaultRouteTableId); await DeleteInternetGateway(vcnClient, ig.Id); } if (subnet != null) { await DeleteSubnet(vcnClient, subnet); } if (vcn != null) { await DeleteVcn(vcnClient, vcn); } } catch (Exception e) { logger.Error($"Failed to clean the resources: {e}"); } finally { fnManagementClient.Dispose(); vcnClient.Dispose(); identityClient.Dispose(); } }
/** * Deletes an Application and waits for it to be deleted. * * @param fnManagementClient the service client to use to delete the Application. * @param applicationId the Application to delete. */ private static async Task DeleteApplication(FunctionsManagementClient fnManagementClient, string applicationId) { // Delete the specified Application var deleteApplicationRequest = new DeleteApplicationRequest { ApplicationId = applicationId }; await fnManagementClient.DeleteApplication(deleteApplicationRequest); logger.Info($"Application deleted: {AppName}"); }
/** * Deletes a Function and waits for it to be deleted. * * @param fnManagementClient the service client to use to delete the Function. * @param functionId the Function to delete. */ private static async Task DeleteFunction(FunctionsManagementClient fnManagementClient, string functionId) { // Delete the specified function var deleteFunctionRequest = new DeleteFunctionRequest { FunctionId = functionId }; await fnManagementClient.DeleteFunction(deleteFunctionRequest); logger.Info($"Function deleted: {FunctionName}"); }
/** * Gets the Application info of a single uniquely named Application in the specified compartment. * * @param fnManagementClient the service client to use to get the Application information. * @param compartmentId of the application. * @param applicationDisplayName of the application. * @return the ApplicationSummary. */ private static async Task <ApplicationSummary> GetUniqueApplicationByName(FunctionsManagementClient fnManagementClient, string compartmentId) { var listApplicationRequest = new ListApplicationsRequest { DisplayName = AppName, CompartmentId = compartmentId }; var listApplicationResponse = await fnManagementClient.ListApplications(listApplicationRequest); if (listApplicationResponse.Items.Count != 1) { logger.Error($"Could not find unique application with name: {AppName} in compartment: {compartmentId}"); return(null); } return(listApplicationResponse.Items[0]); }
/** * Gets Function information. This is an expensive operation and the results should be cached. * * @param fnManagementClient the service client to use to get the Function information. * @param applicationId of the application. * @param functionDisplayName the function name to search for. * @return the FunctionSummary. */ private static async Task <FunctionSummary> GetUniqueFunctionByName(FunctionsManagementClient fnManagementClient, string applicationId, string functionDisplayName) { var listFunctionsRequest = new ListFunctionsRequest { ApplicationId = applicationId, DisplayName = functionDisplayName }; var listFunctionsResponse = await fnManagementClient.ListFunctions(listFunctionsRequest); if (listFunctionsResponse.Items.Count != 1) { logger.Error($"Could not find function with name: {functionDisplayName} in application: {applicationId}"); return(null); } return(listFunctionsResponse.Items[0]); }
/** * Create all the OCI and Fn resources required to invoke a function. * * @param provider the OCI credentials provider. * @param compartmentId the compartment in which to create the required * resources. * @param image a valid OCI Registry image for the function. */ private static async Task SetUpResources(IBasicAuthenticationDetailsProvider provider, string compartmentId, string image) { logger.Info("Setting up resources"); var identityClient = new IdentityClient(provider); var vcnClient = new VirtualNetworkClient(provider); var fnManagementClient = new FunctionsManagementClient(provider); Vcn vcn = null; Subnet subnet = null; InternetGateway internetGateway = null; try { AvailabilityDomain availablityDomain = await GetAvailabilityDomain(identityClient, compartmentId); logger.Info($"availability domain is {availablityDomain.Name}"); vcn = await CreateVcn(vcnClient, compartmentId); internetGateway = await CreateInternalGateway(vcnClient, compartmentId, vcn); await AddInternetGatewayToDefaultRouteTable(vcnClient, vcn.DefaultRouteTableId, internetGateway.Id); subnet = await CreateSubnet(vcnClient, compartmentId, availablityDomain.Name, vcn.Id); var subnetIds = new List <string>() { subnet.Id }; Application app = await CreateApplication(fnManagementClient, compartmentId, subnetIds); long memoryInMBs = 128L; int timeoutInSeconds = 30; Function fn = await CreateFunction(fnManagementClient, app.Id, image, memoryInMBs, timeoutInSeconds); } catch (Exception e) { logger.Error($"failed to setup resources: {e}"); } finally { fnManagementClient.Dispose(); vcnClient.Dispose(); identityClient.Dispose(); } }
/** * Gets Function information. This is an expensive operation and the results should be cached. * * @param fnManagementClient the service client to use to get the Function information. * @param compartmentId of the application and function. * @return the FunctionSummary. */ private static async Task <FunctionSummary> GetUniqueFunctionByName(FunctionsManagementClient fnManagementClient, string compartmentId) { var application = await GetUniqueApplicationByName(fnManagementClient, compartmentId); return(await GetUniqueFunctionByName(fnManagementClient, application.Id, FunctionName)); }