# The generic data model to define applications and abstractions So instead of creating a in-house CRD, we decide to work out a generic design which can be applied to all use cases at least in Alibaba. The first idea is, we should provide several building blocks to be able to define higher level abstractions per request by developers and operators. but without coupling with specific workload types or platforms. This is how this model differentiates from platform level solutions like Serverless/FaaS/PaaS. Bringing your own workloads and platform is the key. The second idea is "separate concerns" instead of "a mixed bag". We premises that app developers, app operators (or automated operation platforms) and infrastructure engineers tend to focus on their own piece of data . Note that we will try to avoid any form of information isolation at the meantime. In general, the model is composed by two parts: 1. Application: a group of runnable components. 2. ApplicationConfiguration: a object to claim and apply operational capabilities to every component. ### Application This part which is the main concern for *developers*. ![](https://i.imgur.com/vdspTrr.png) *Component* is the piece of data to define "what to run". It's basically a wrapper of specific workload which is defined by given Custom Resource Definition (CRD). For example, you can define your own `WebServer` Custom Resource as a component like below: ```yaml apiVersion: core.oam.dev/v1alpha2 kind: Component metadata: name: frontend spec: workload: apiVersion: myapp.dev/v1 kind: WebServer spec: containers: - name: my-nginx image: nginx:1.16.1 resources: limits: memory: "200Mi" ports: - containerPort: 4848 protocol: "TCP" env: - name: WORDPRESS_DB_PASSWORD value: "" ``` Or, a `Function` component: ```yaml apiVersion: core.oam.dev/v1alpha2 kind: Component metadata: name: function-frontend spec: workload: # this is a real FaaS workload in Alibaba apiVersion: faas.alibaba.com/v1 kind: Function spec: runtime: java8 timeoutMilliseconds: 3000 blobCodeUrl: http://xxx/f36286e6-f070-498f-a520-6dd3a589bd90 env: - name: debug value: "true" resources: cpu: required: 1 memory: required: 2048M triggers: - type: http - type: metaq ``` It could also be cloud resource of course, for example, a MySQL database defined by Crossplane which can be provided by AWS or AlibabaCloud: ```yaml apiVersion: core.oam.dev/v1alpha2 kind: Component metadata: name: cloud-postgres-db spec: workload: apiVersion: database.crossplane.io/v1alpha1 kind: PostgreSQLInstance metadata: name: app-postgresql spec: classSelector: matchLabels: {} writeConnectionSecretToRef: name: postgresqlconn engineVersion: "9.6" ``` The modern application is usually composed by multiple components, e.g. a Wordpress (PHP code + MySQL), or a machine learning training app (Parameter Server + Worker) etc. ### ApplicationConfiguration This part is concern for *operators* or *automatic system* (e.g. PaaS/Serverless etc). ![](https://i.imgur.com/2cn1DS2.png) For components belonging to same application, ApplicationConfiguration object will reference them together. For every component in the same configuration, operators (or the system) can apply various operational capabilities to it, for example, manual/auto scaling policy, routing policy, rollout strategy etc. All these capabilities are named as *Traits* for component. This concept is borrowed from [trait system](https://doc.rust-lang.org/1.8.0/book/traits.html) from Rust language, i.e. the operational characteristics for the app. ```yaml apiVersion: core.oam.dev/v1alpha2 kind: ApplicationConfiguration metadata: name: frontend-db-config spec: components: - componentName: cloud-postgres-db - componentName: frontend traits: - trait: apiVersion: core.oam.dev/v1alpha2 kind: ManualScalerTrait metadata: name: frontend-scaler spec: replicaCount: 2 ``` There's a special kind of trait named *Scope*. Unlike trait which must be per component, scope is designed to be shared by different components within the same application. // TBD: continue to explain the model.