# apidApigeeSync

This core plugin for [apid](http://github.com/30x/apid) connects to the Apigee Change Agent and publishes the data
changes events onto the apid Event service. It also coordinates DB initialization for plugins on startup.

### Configuration

| name                         | description              |
|------------------------------|--------------------------|
| apigeesync_poll_interval     | int. seconds. default: 5 |
| apigeesync_proxy_server_base | string. url. required.   |
| apigeesync_consumer_key      | string. required.        |
| apigeesync_consumer_secret   | string. required.        |
| apigeesync_instance_name     | string. optional. Display Name for UI        |

This plugin also populates a configuration item for dependant plugins that may need it:

| name                         | description              |
|------------------------------|--------------------------|
| apigeesync_apid_instance_id  | string                   |

### Event Generated

* Selector: "ApigeeSync"
* Data: [payload.go](payload.go)

### Startup Procedure

#### ApigeeSync
1. Read DB version (Snapshot.SnapshotInfo) from default DB
2. If version found, emit Snapshot event (using Snapshot.SnapshotInfo, no data)
3. Ask server for Snapshot
4. Each time a Snapshot is received
    1. Verify Snapshot.SnapshotInfo is different than current
    2. Stop processing change events
    3. Remove or clean new DB version if it exists
    4. Emit Snapshot event
    5. Wait for plugins to finish processing
    6. Save Snapshot.SnapshotInfo in default DB
    7. Release old DB version
    8. Start processing change events

#### ApigeeSync-dependent plugins
1. Initialization
    1. Until receiving first Snapshot message, ApigeeSync-dependent APIs must either:
         1. not register (endpoint will return a 404 by default) 
         2. return a 503 until DB is initialized
2. Upon receiving a snapshot notification (this is a HOT DB upgrade)
    1. Get DB for version (use Snapshot.SnapshotInfo as version)
    2. Create plugin's tables, if needed
    3. Insert any snapshot data into plugin's tables
    4. Set reference to new DB for all data access
    5. If db-dependent services are not exposed yet, expose them

Example plugin code:

    var (
      log      apid.LogService   // set in initPlugin
      data     apid.DataService
      unsafeDB apid.DB
      dbMux    sync.RWMutex
    )
    
    func init() {
      apid.RegisterPlugin(initPlugin)
    }
    
    func initPlugin(services apid.Services) error {
      log = services.Log().ForModule("examplePlugin")
      log.Debug("start init")
      data = services.Data()
      return nil
    }
    
    // always use getDB() to safely access current DB
    func getDB() apid.DB {
      dbMux.RLock()
      db := unsafeDB
      dbMux.RUnlock()
      return db
    }
    
    func setDB(db apid.DB) {
      dbMux.Lock()
      if unsafeDB == nil { // init API on DB initialization (optional)
        go initAPI()
      }
      unsafeDB = db
      dbMux.Unlock()
    }

    func processSnapshot(snapshot *common.Snapshot) {
    
      log.Debugf("Snapshot received. Switching to DB version: %s", snapshot.SnapshotInfo)
    
      db, err := data.DBVersion(snapshot.SnapshotInfo)
      if err != nil {
        log.Panicf("Unable to access database: %v", err)
      }

      // init DB as needed (note: DB may exist, use 'CREATE TABLE IF NOT EXISTS' if not explicitly checking)
      initDB(db)
    
      for _, table := range snapshot.Tables {
        // populate tables from snapshot...
      }
    
      // switch to new database 
      setDB(db)
      log.Debug("Snapshot processed")
    }
