This is the second article in a two-part series. The first part is here.
Service virtualization is uniquely suited to support the needs of cloud-native applications. The solution’s principles support all the key attributes of cloud-native architectures. I would contend that service virtualization and cloud-native architectures are built for one another. Just as service virtualization is considered essential for agile development, it is just as necessary for supporting cloud-native applications.
In this section, we will discuss how Broadcom Service Virtualization supports each of the 10 key attributes of cloud-native application systems.
Continuous Microservices Application Development and Testing
One of the key attributes of cloud-native applications is the use of loosely coupled components, such as microservices. Because component-based systems have numerous dependencies on each other, use of service virtualization is especially necessary to support the agile development, testing, and continuous delivery of such applications. This is one of the most popular use cases for service virtualization. See figure below.
Service virtualization can be used to support every aspect of microservices testing, including unit, component, integration, contract, and system testing. Plus, testing can be done continuously throughout the CI/CD pipeline. For more details on using service virtualization for component-based applications, please refer to my previous blogs (Continuous Service Virtualization Part 1 and Part 2).
The following sections highlight a few key use cases:
a. Generation of Synthetic Virtual Services from Microservice APIs
Service virtualization can be used to generate a synthetic virtual service for a dependent component that does not yet exist, or is unavailable, using synthetic request-response pairs based on the API’s definition of the service. This is especially useful during development and unit testing.
The synthetic virtual service may be progressively enhanced to support subsequent testing (such as integration and system tests) along the CI/CD lifecycle.
b. Support for Microservices Contract Testing
A service consumer can test a service provider using synthetic request-response pairs developed from its API specification. A service provider can in turn test its interactions with a consumer using a validated contract—which can be implemented using a recorded virtual service. See figure below.
c. Support for Continuous Microservices Performance Testing
This is one of the most important use cases for service virtualization. With service virtualization, we can truly shift microservices performance testing left. This significantly reduces the need for time consuming, end-to-end load tests that have to be conducted before release. Service virtualization enables limited, scaled performance testing at the component level to validate associated service level objectives (SLOs). This also enables scaled testing of transactions across multiple services using their APIs. For more details on this, please refer to my prior blog on continuous performance of microservices.
d. Support for Easier Chaos and Negative Testing
Virtual services provide a means to support repeatable and structured chaos and detrimental conditions testing. For example, they can simulate such conditions as non-responsiveness, downtime, or slow response time. This is much easier and far less time consuming than having to power off servers or take down physical computing instances.
e. Support for Continuous Reliability Engineering
Use cases (c) and (d) above allow us to continuously validate the reliability of cloud-based applications by applying the principles of continuous testing at the component level. In this way, we can test every component change early in the lifecycle to see if its SLOs are met. With service virtualization, we can simulate dependent components along with their SLOs (or SLIs if SLOs are not available). For more information, please refer to my blog on Continuous Reliability.
Support for Self-Service, Virtual, Shared, and Elastic Infrastructure
This is the second key attribute for cloud-native applications. As discussed in section III, teams can use virtual services as a stand-in for real components. Virtual services can easily be packaged into lightweight container-based VSEs, which can be deployed on-demand into ephemeral cloud environments and they can scale automatically as needed.
In fact, libraries of virtual services may themselves be offered as a service (see “Service Virtualization as a Service”)—with all the capabilities of a cloud-native service—so that they may governed and consumed across multiple teams and applications.
Support for Isolation from Server and Operation System Dependencies
Virtual services can be packaged into containers that may be ported across a variety of computer environments, regardless of where the real end points are hosted. Plus, they can be deployed across multiple hybrid computing environments with different types of hardware and OS. This not only includes cloud-native applications, but legacy systems (such as mainframes) and other complex systems that these applications need to interact with.
One use case of this characteristic is service virtualization’s support for testing cloud-native applications with function-as-a-service (FaaS) dependencies. Generally speaking, FaaS implementations are not very portable across multiple cloud providers. This makes it difficult to incorporate FaaS code into testing environments that may reside in a different cloud. Service virtualization can be used to virtualize the FaaS component so it can be deployed into a local testing environment with automatically scaling VSEs. This enables teams to simulate the FaaS behavior for an application under test that depends on a FaaS endpoint.
Support for Independent Lifecycle Management Using Agile/DevOps
Support for independent life cycle management is one of the key use cases for service virtualization. (See my previous blog for more on this topic.) Service virtualization helps to optimize continuous delivery. In fact, virtual services are key to supporting the principal of having a dedicated CI/CD pipeline for each microservice.
Since microservices have dependencies on each other, this means that individual CI/CD pipelines may be impeded when a dependent microservice is not available or is undergoing parallel development. Virtual services help to remove these dependencies between parallel pipelines. Virtual services can be made available to other services as needed. See figure below.
Note: This principle can be used to support easier canary testing. Cloud-native applications are designed to allow frequent micro releases, for example, of a single component. This allows us to get fast feedback by deploying only the changed component into a canary environment. Service virtualization makes this much easier and more cost-effective by virtualizing the rest of the application ecosystem, enabling teams to focus on the behavior of only the changed component.
Service virtualization supports a rich set of APIs that can be used to integrate with CI/CD and other tools for automation of deployment, orchestration, updates, and more.
Support for Lightweight Containers
Virtual services can easily be packaged into lightweight containers. In addition, VSEs can be deployed on-demand into ephemeral cloud environments, and scale automatically as required in Kubernetes clusters.
Support for Best-of-Breed Languages and Frameworks
Virtual services are built at the protocol level, and therefore are generally able to support applications, irrespective of the programming language they are developed in. This allows us to build virtual services for applications that have been created with a broad range of languages and platforms.
For developers, virtual services may be also be developed as code and this approach is supported by many programming languages.
Support for API-Based Interaction and Collaboration
As discussed before, service virtualization allows us to create synthetic virtual services from service API specifications. It also supports extensive API-based testing (including what’s referred to as “headless” testing) across layers of APIs typically used in cloud-based applications.
In addition, virtual services don’t just support simple API protocols like REST. Virtual services can support a variety of API types (such as gRPC) across multiple types of application systems.
The figure below shows a common API architecture that has experience, process, and system APIs. Service virtualization can be used to not only virtualize each of the sub-services that support the API, but the entire API layer by virtualizing the “nearest neighbor.”
For example, we can run user-experience tests on front-end devices by virtualizing the “omni-channel” API—without having to set up a test environment for the all the complicated stacks below it!
In addition, service virtualization supports a rich set of APIs that can be used to integrate with CI/CD and other tools for automation of deployment, orchestration, updates, and more.
Service virtualization can also be integrated with API Gateways to allow transparent access to API back-end services—whether implemented by a real service or a virtual service. See figure below.
Support for Stateless and Stateful Services
Virtual services can be easily created to be stand-ins for stateless services by simulating their behavior.
When we need to virtualize a stateful service, we can create virtual services that are supported by extensive test data that represents a sub-set of the stateful service’s data. We can do so by integrating with a test data management system. For more on the interaction between virtual services and test data in the context of microservices, please refer to my prior blog on continuous test data management.
Support for Automation and Infrastructure-as-Code
Virtual services are highly amenable to automated deployment (for example in CI/CD pipelines), especially when packaged as containers. These services can be defined as part of infrastructure-as-code environment recipes, such as Helm Charts, for automated provisioning and deployment.
Support for Governance Models
Virtual services are typically deployed into Virtual Service Environments. This allows us to define governance policies of virtual services that mimic those of corresponding applications.
Summary and Conclusion
We have examined how Broadcom Service Virtualization supports a wide variety of use cases for cloud computing—from cloud migration to support for cloud-native computing.
Our view is that service virtualization and cloud capabilities complement each other. By combining Service virtualization and cloud services, teams can establish a level of truly agile application development and delivery, which would simply not be possible with only one of these capabilities on its own. In fact, teams need to use service virtualization to support the requirements of cloud-native systems.