---
# System prepended metadata

title: The generic data model to define applications and abstractions

---

# 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.




