VOL-1460
I need to test out a method sharing protos.
In particular, it is the protos under the go/folder

Plus some updates to the build process.

Change-Id: I5878354fd1ef136d4f0a019b22de96afdb0205e1
diff --git a/go/voltha/adapter.proto b/go/voltha/adapter.proto
new file mode 100644
index 0000000..e8889c5
--- /dev/null
+++ b/go/voltha/adapter.proto
@@ -0,0 +1,43 @@
+syntax = "proto3";
+
+option go_package = "github.com/opencord/voltha-protos/go/voltha";
+
+package voltha;
+
+import "google/protobuf/any.proto";
+import "voltha_protos/common.proto";
+import "voltha_protos/meta.proto";
+
+
+message AdapterConfig {
+
+    // Common adapter config attributes here
+    LogLevel.LogLevel log_level = 1;
+
+    // Custom (vendor-specific) configuration attributes
+    google.protobuf.Any additional_config = 64;
+
+}
+
+// Adapter (software plugin)
+message Adapter {
+
+    // Unique name of adapter, matching the python package name under
+    // voltha/adapters.
+    string id = 1 [(access) = READ_ONLY];
+    string vendor = 2 [(access) = READ_ONLY];
+    string version = 3 [(access) = READ_ONLY];
+
+    // Adapter configuration
+    AdapterConfig config = 16;
+
+    // Custom descriptors and custom configuration
+    google.protobuf.Any additional_description = 64 [(access) = READ_ONLY];
+
+    repeated string logical_device_ids = 4;  // Logical devices "owned"
+
+}
+
+message Adapters {
+    repeated Adapter items = 1;
+}
diff --git a/go/voltha/device.proto b/go/voltha/device.proto
new file mode 100644
index 0000000..bbe8894
--- /dev/null
+++ b/go/voltha/device.proto
@@ -0,0 +1,329 @@
+syntax = "proto3";
+
+option go_package = "github.com/opencord/voltha-protos/go/voltha";
+
+package voltha;
+
+import "google/protobuf/any.proto";
+import "voltha_protos/common.proto";
+import "voltha_protos/meta.proto";
+import "voltha_protos/openflow_13.proto";
+import "voltha_protos/yang_options.proto";
+
+// A Device Type
+message DeviceType {
+
+    // Unique name for the device type
+    string id = 1;
+
+    // Unique vendor id for the device type applicable to ONU
+    // 4 bytes of vendor id from ONU serial number
+    string vendor_id = 5;
+
+    repeated string vendor_ids = 6;
+
+    // Name of the adapter that handles device type
+    string adapter = 2;
+
+    // Capabilities
+    bool accepts_bulk_flow_update = 3;
+    bool accepts_add_remove_flow_updates = 4;
+    bool accepts_direct_logical_flows_update = 7;
+
+}
+
+// A plurality of device types
+message DeviceTypes {
+    repeated DeviceType items = 1;
+}
+
+message PmConfig {
+    enum PmType {
+        COUNTER = 0;
+        GAUGE = 1;
+        STATE = 2;
+        CONTEXT = 3;
+    }
+    string name = 1;
+    PmType type = 2;
+    bool enabled = 3; // Whether or not this metric makes it to Kafka
+    uint32 sample_freq = 4; // Sample rate in 10ths of a second
+}
+
+message PmGroupConfig {
+    string group_name = 1;
+    uint32 group_freq = 2; // Frequency applicable to the grop
+    bool enabled = 3; // Enable/disable group level only
+    repeated PmConfig metrics = 4;
+}
+
+message PmConfigs {
+    string id = 1; // To work around a chameleon POST bug
+    uint32 default_freq = 2; // Default sample rate
+    // Forces group names and group semantics
+    bool grouped = 3 [(access) = READ_ONLY];
+    // Allows Pm to set an individual sample frequency
+    bool freq_override = 4 [(access) = READ_ONLY];
+    repeated PmGroupConfig groups = 5; // The groups if grouped is true
+    repeated PmConfig metrics = 6; // The metrics themselves if grouped is false.
+}
+
+// Describes instance of software image on the device
+message Image {
+    string name = 1;                // software patch name
+    string version = 2;             // version of software
+    string hash = 3;                // md5 hash
+    string install_datetime = 4;    // combined date and time expressed in UTC.
+                                    // use ISO 8601 format for date and time
+
+    // The active software image is one that is currently loaded and executing
+    // in the ONU or circuit pack. Under normal operation, one software image
+    // is always active while the other is inactive. Under no circumstances are
+    // both software images allowed to be active at the same time
+    bool is_active = 5;             // True if the image is active
+
+    // The committed software image is loaded and executed upon reboot of the
+    // ONU and/or circuit pack. During normal operation, one software image is
+    // always committed, while the other is uncommitted.
+    bool is_committed = 6;          // True if the image is committed
+
+    // A software image is valid if it has been verified to be an executable
+    // code image. The verification mechanism is not subject to standardization;
+    // however, it should include at least a data integrity (e.g., CRC) check of
+    // the entire code image.
+    bool is_valid = 7;              // True if the image is valid
+}
+
+// List of software on the device
+message Images {
+    repeated Image image = 1;
+}
+
+message ImageDownload {
+    option (yang_child_rule) = MOVE_TO_PARENT_LEVEL;
+
+    enum ImageDownloadState {
+        DOWNLOAD_UNKNOWN = 0;
+        DOWNLOAD_SUCCEEDED = 1;
+        DOWNLOAD_REQUESTED = 2;
+        DOWNLOAD_STARTED = 3;
+        DOWNLOAD_FAILED = 4;
+        DOWNLOAD_UNSUPPORTED = 5;
+        DOWNLOAD_CANCELLED = 6;
+    }
+
+    enum ImageDownloadFailureReason {
+        NO_ERROR = 0;
+        INVALID_URL = 1;
+        DEVICE_BUSY = 2;
+        INSUFFICIENT_SPACE = 3;
+        UNKNOWN_ERROR = 4;
+        CANCELLED = 5;
+    }
+
+    enum ImageActivateState {
+        IMAGE_UNKNOWN = 0;
+        IMAGE_INACTIVE = 1;
+        IMAGE_ACTIVATING = 2;
+        IMAGE_ACTIVE = 3;
+        IMAGE_REVERTING = 4;
+        IMAGE_REVERTED = 5;
+    }
+
+    // Device Identifier
+    string id = 1;
+
+    // Image unique identifier
+    string name = 2;
+
+    // URL where the image is available
+    // should include username password
+    string url = 3;
+
+    // CRC of the image to be verified aginst
+    uint32 crc = 4;
+
+    // Download state
+    ImageDownloadState download_state = 5;
+
+    // Downloaded version
+    string image_version = 6;
+
+    // Bytes downloaded
+    uint32 downloaded_bytes = 7;
+
+    // Download failure reason
+    ImageDownloadFailureReason reason= 8;
+
+    // Additional info
+    string additional_info = 9;
+
+    // Save current configuration
+    bool save_config = 10;
+
+    // Image local location
+    string local_dir = 11;
+
+    // Image activation state
+    ImageActivateState image_state = 12;
+    
+    // Image file size
+    uint32 file_size = 13;
+}
+
+message ImageDownloads {
+    repeated ImageDownload items = 2;
+}
+
+message Port {
+    option (voltha.yang_child_rule) = MOVE_TO_PARENT_LEVEL;
+
+    enum PortType {
+        UNKNOWN = 0;
+        ETHERNET_NNI = 1;
+        ETHERNET_UNI = 2;
+        PON_OLT = 3;
+        PON_ONU = 4;
+        VENET_OLT = 5;
+        VENET_ONU = 6;
+    }
+
+    uint32 port_no = 1;  // Device-unique port number
+
+    string label = 2;  // Arbitrary port label
+
+    PortType type = 3;  //  Type of port
+
+    AdminState.AdminState admin_state = 5;
+
+    OperStatus.OperStatus oper_status = 6;
+
+    string device_id = 7;  // Unique .id of device that owns this port
+
+    message PeerPort {
+        string device_id = 1;
+        uint32 port_no = 2;
+    }
+    repeated PeerPort peers = 8;
+
+    fixed64 rx_packets = 9;
+    fixed64 rx_bytes = 10;
+    fixed64 rx_errors = 11;
+    fixed64 tx_packets = 12;
+    fixed64 tx_bytes = 13;
+    fixed64 tx_errors = 14;
+
+}
+
+message Ports {
+    repeated Port items = 1;
+}
+
+// A Physical Device instance
+message Device {
+    option (voltha.yang_child_rule) = MOVE_TO_PARENT_LEVEL;
+
+    // Voltha's device identifier
+    string id = 1 [(access) = READ_ONLY];
+
+    // Device type, refers to one of the registered device types
+    string type = 2 [(access) = READ_ONLY];
+
+    // Is this device a root device. Each logical switch has one root
+    // device that is associated with the logical flow switch.
+    bool root = 3 [(access) = READ_ONLY];
+
+    // Parent device id, in the device tree (for a root device, the parent_id
+    // is the logical_device.id)
+    string parent_id = 4 [(access) = READ_ONLY];
+    uint32 parent_port_no = 20 [(access) = READ_ONLY];
+
+    // Vendor, version, serial number, etc.
+    string vendor = 5 [(access) = READ_ONLY];
+    string model = 6 [(access) = READ_ONLY];
+    string hardware_version = 7 [(access) = READ_ONLY];
+    string firmware_version = 8 [(access) = READ_ONLY];
+    // List of software on the device
+    Images images = 9 [(access) = READ_ONLY];
+    string serial_number = 10 [(access) = READ_ONLY];
+    string vendor_id = 24 [(access) = READ_ONLY];
+
+    // Addapter that takes care of device
+    string adapter = 11 [(access) = READ_ONLY];
+
+    // Device contact on vlan (if 0, no vlan)
+    uint32 vlan = 12;
+
+    message ProxyAddress {
+        string device_id = 1;  // Which device to use as proxy to this device
+        string device_type = 2; // The device type of the proxy device to use as the adapter name
+        uint32 channel_id = 3;  // Sub-address within proxy
+        uint32 channel_group_id = 4; // Channel Group index
+        string channel_termination = 5; // Channel Termination name
+        uint32 onu_id = 6; // onu identifier; optional
+        uint32 onu_session_id = 7; // session identifier for the ONU; optional
+    };
+
+    // Device contact MAC address (format: "xx:xx:xx:xx:xx:xx")
+    string mac_address = 13;
+
+    oneof address {
+
+        // Device contact IPv4 address (format: "a.b.c.d" or can use hostname too)
+        string ipv4_address = 14;
+
+        // Device contact IPv6 address using the canonical string form
+        // ("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")
+        string ipv6_address = 15;
+
+        string host_and_port = 21;
+
+    };
+    string extra_args = 23;  // Used to pass additional device specific arguments
+
+    ProxyAddress proxy_address = 19;
+
+    AdminState.AdminState admin_state = 16;
+
+    OperStatus.OperStatus oper_status = 17 [(access) = READ_ONLY];
+
+    string reason = 22 [(access) = READ_ONLY];  //  Used in FAILED state
+
+    ConnectStatus.ConnectStatus connect_status = 18 [(access) = READ_ONLY];
+
+    // TODO additional common attribute here
+
+    // Device type specific attributes
+    google.protobuf.Any custom = 64;
+
+    repeated Port ports = 128  [(child_node) = {key: "port_no"}];
+    openflow_13.Flows flows = 129 [(child_node) = {}];
+    openflow_13.FlowGroups flow_groups = 130 [(child_node) = {}];
+    // PmConfigs will eventually converted to a child node of the
+    // device to falicitata callbacks and to simplify manipulation.
+    PmConfigs pm_configs = 131 [(child_node) = {}];
+
+    repeated ImageDownload image_downloads = 133 [(child_node) = {key: "name"}];
+}
+
+message Devices {
+    repeated Device items = 1;
+}
+
+message SimulateAlarmRequest {
+    enum OperationType {
+        RAISE = 0;
+        CLEAR = 1;
+    }
+    // Device Identifier
+    string id = 1;
+    string indicator = 2;
+    string intf_id = 3;
+    string port_type_name = 4;
+    string onu_device_id = 5;
+    int32 inverse_bit_error_rate = 6;
+    int32 drift = 7;
+    int32 new_eqd = 8;
+    string onu_serial_number = 9;
+    OperationType operation = 10;
+}
diff --git a/go/voltha/events.proto b/go/voltha/events.proto
new file mode 100644
index 0000000..0a2c0e4
--- /dev/null
+++ b/go/voltha/events.proto
@@ -0,0 +1,195 @@
+syntax = "proto3";
+
+option go_package = "github.com/opencord/voltha-protos/go/voltha";
+
+package voltha;
+
+import "voltha_protos/meta.proto";
+import "google/api/annotations.proto";
+
+message ConfigEventType {
+    enum ConfigEventType {
+        add = 0; // A new config has been added
+        remove = 1; // A config has been removed
+        update = 2; // A config has been updated
+    }
+}
+
+message ConfigEvent {
+    ConfigEventType.ConfigEventType type = 1;
+
+    string hash = 2; // hash for this change, can be used for quick lookup
+    string data = 3; // the actual new data, in json format
+}
+
+message KpiEventType {
+    enum KpiEventType {
+        slice = 0; // slice: a set of path/metric data for same time-stamp
+        ts = 1; // time-series: array of data for same metric
+    }
+}
+
+/*
+ * Struct to convey a dictionary of metric metadata.
+ */
+message MetricMetaData {
+    string title = 1;   // Metric group or individual metric name
+    double ts = 2;      // UTC time-stamp of data (seconds since epoch) of
+                        // when the metric or metric group was collected.
+                        // If this is a 15-min historical group, it is the
+                        // time of the collection and reporting, not the
+                        // start or end of the 15-min group interval.
+
+    string logical_device_id = 3; // The logical device ID of the VOLTHA
+                                  // (equivalent to the DPID that ONOS has
+                                  // for the VOLTHA device without the
+                                  //  'of:' prefix
+    string serial_no = 4;         // The OLT, ONU, ... device serial number
+    string device_id = 5;         // The OLT, ONU, ... physical device ID
+
+    map<string, string> context = 6; // Name value pairs that provide additional
+                                     // context information on the metrics being
+                                     // reported.
+}
+
+/*
+ * Struct to convey a dictionary of metric->value pairs. Typically used in
+ * pure shared-timestamp or shared-timestamp + shared object prefix situations.
+ */
+message MetricValuePairs {
+
+    // Metric / value pairs.
+    map<string, float> metrics = 1;
+
+}
+
+/*
+ * Struct to group metadata for a metric (or group of metrics) with the key-value
+ * pairs of collected metrics
+ */
+message MetricInformation {
+    MetricMetaData metadata = 1;
+    map<string, float> metrics = 2;
+}
+
+/*
+ * Legacy KPI Event structured.  In mid-August, the KPI event format was updated
+ *                               to a more easily parsable format. See VOL-1140
+ *                               for more information.
+ */
+message KpiEvent {
+
+    KpiEventType.KpiEventType type = 1;
+
+    // Fields used when for slice:
+
+    float ts = 2; // UTC time-stamp of data in slice mode (seconds since epoc)
+
+    map<string, MetricValuePairs> prefixes = 3;
+
+}
+
+message KpiEvent2 {
+    // Type of KPI Event
+    KpiEventType.KpiEventType type = 1;
+
+    // Fields used when for slice:
+    double ts = 2;  // UTC time-stamp of data in slice mode (seconds since epoch)
+                    // of the time this entire KpiEvent was published to the kafka bus
+
+    repeated MetricInformation slice_data = 3;
+}
+
+/*
+ * Identify to the area of the system impacted by the alarm
+ */
+message AlarmEventType {
+    enum AlarmEventType {
+        COMMUNICATION = 0;
+        ENVIRONMENT = 1;
+        EQUIPMENT = 2;
+        SERVICE = 3;
+        PROCESSING = 4;
+        SECURITY = 5;
+    }
+}
+
+/*
+ * Identify to the functional category originating the alarm
+ */
+message AlarmEventCategory {
+    enum AlarmEventCategory {
+        PON = 0;
+        OLT = 1;
+        ONT = 2;
+        ONU = 3;
+        NNI = 4;
+    }
+}
+
+/*
+ * Active state of the alarm
+ */
+message AlarmEventState {
+    enum AlarmEventState {
+        RAISED = 0;
+        CLEARED = 1;
+    }
+}
+
+/*
+ * Identify the overall impact of the alarm on the system
+ */
+message AlarmEventSeverity {
+    enum AlarmEventSeverity {
+        INDETERMINATE = 0;
+        WARNING = 1;
+        MINOR = 2;
+        MAJOR = 3;
+        CRITICAL = 4;
+    }
+}
+
+/*
+ *
+ */
+message AlarmEvent {
+    // Unique ID for this alarm.  e.g. voltha.some_olt.1234
+    string id = 1;
+
+    // Refers to the area of the system impacted by the alarm
+    AlarmEventType.AlarmEventType type = 2;
+
+    // Refers to functional category of the alarm
+    AlarmEventCategory.AlarmEventCategory category = 3;
+
+    // Current active state of the alarm
+    AlarmEventState.AlarmEventState state = 4;
+
+    // Overall impact of the alarm on the system
+    AlarmEventSeverity.AlarmEventSeverity severity = 5;
+
+    // Timestamp at which the alarm was first raised
+    float raised_ts = 6;
+
+    // Timestamp at which the alarm was reported
+    float reported_ts = 7;
+
+    // Timestamp at which the alarm has changed since it was raised
+    float changed_ts = 8;
+
+    // Identifier of the originating resource of the alarm
+    string resource_id = 9;
+
+    // Textual explanation of the alarm
+    string description = 10;
+
+    // Key/Value storage for extra information that may give context to the alarm
+    map<string, string> context = 11;
+
+    // logical device id
+    string logical_device_id = 12;
+
+    // alarm_type  name indicates clearly the name of the alarm
+    string alarm_type_name = 13;
+}
diff --git a/go/voltha/health.proto b/go/voltha/health.proto
new file mode 100644
index 0000000..7721825
--- /dev/null
+++ b/go/voltha/health.proto
@@ -0,0 +1,36 @@
+syntax = "proto3";
+
+option go_package = "github.com/opencord/voltha-protos/go/voltha";
+
+package voltha;
+
+import "google/api/annotations.proto";
+import "google/protobuf/empty.proto";
+import "voltha_protos/meta.proto";
+
+// Encode health status of a Voltha instance
+message HealthStatus {
+
+    // Health states
+    enum HealthState {
+        HEALTHY = 0;  // The instance is healthy
+        OVERLOADED = 1;  // The instance is overloaded, decrease query rate
+        DYING = 2;  // The instance is in a critical condition, do not use it
+    }
+
+    // Current state of health of this Voltha instance
+    HealthState state = 1 [(access) = READ_ONLY];
+}
+
+// Health related services
+service HealthService {
+
+    // Return current health status of a Voltha instance
+    rpc GetHealthStatus(google.protobuf.Empty) returns (HealthStatus) {
+        option (google.api.http) = {
+            get: "/health"
+        };
+    }
+
+}
+
diff --git a/go/voltha/logical_device.proto b/go/voltha/logical_device.proto
new file mode 100644
index 0000000..6e3a233
--- /dev/null
+++ b/go/voltha/logical_device.proto
@@ -0,0 +1,61 @@
+syntax = "proto3";
+
+option go_package = "github.com/opencord/voltha-protos/go/voltha";
+
+package voltha;
+
+import "google/api/annotations.proto";
+import "voltha_protos/meta.proto";
+import "voltha_protos/openflow_13.proto";
+
+message LogicalPortId {
+    // unique id of logical device
+    string id = 1;
+
+    // id of the port on the logical device
+    string port_id = 2;
+}
+
+message LogicalPort {
+    string id = 1;
+    openflow_13.ofp_port ofp_port = 2;
+    string device_id = 3;
+    uint32 device_port_no = 4;
+    bool root_port = 5;
+}
+
+message LogicalPorts {
+    repeated LogicalPort items = 1;
+}
+
+message LogicalDevice {
+
+    // unique id of logical device
+    string id = 1;
+
+    // unique datapath id for the logical device (used by the SDN controller)
+    uint64 datapath_id = 2;
+
+    // device description
+    openflow_13.ofp_desc desc = 3;
+
+    // device features
+    openflow_13.ofp_switch_features switch_features = 4;
+
+    // name of the root device anchoring logical device
+    string root_device_id = 5;
+
+    // logical device ports
+    repeated LogicalPort ports = 128 [(child_node) = {key: "id"}];
+
+    // flows configured on the logical device
+    openflow_13.Flows flows = 129 [(child_node) = {}];
+
+    // flow groups configured on the logical device
+    openflow_13.FlowGroups flow_groups = 130 [(child_node) = {}];
+
+}
+
+message LogicalDevices {
+    repeated LogicalDevice items = 1;
+}
diff --git a/go/voltha/ponsim.proto b/go/voltha/ponsim.proto
new file mode 100644
index 0000000..d4cbaa2
--- /dev/null
+++ b/go/voltha/ponsim.proto
@@ -0,0 +1,67 @@
+syntax = "proto3";
+
+option go_package = "github.com/opencord/voltha-protos/go/voltha";
+
+package voltha;
+
+import "google/protobuf/empty.proto";
+import "voltha_protos/openflow_13.proto";
+
+
+message PonSimOnuDeviceInfo {
+    int32 uni_port = 1;
+    string serial_number = 2;
+}
+
+message PonSimDeviceInfo {
+    int32 nni_port = 1;
+    repeated PonSimOnuDeviceInfo onus = 2;
+}
+
+message FlowTable {
+    int32 port = 1;  // Used to address right device
+    repeated openflow_13.ofp_flow_stats flows = 2;
+}
+
+message PonSimFrame {
+    string id = 1;
+    bytes payload = 2;
+    int32 out_port = 3;
+}
+
+message PonSimPacketCounter {
+    string name = 1;
+    int64 value = 2;
+}
+
+message PonSimPortMetrics {
+    string port_name = 1;
+    repeated PonSimPacketCounter packets = 2;
+}
+
+message PonSimMetrics {
+    string device = 1;
+    repeated PonSimPortMetrics metrics = 2;
+}
+
+message PonSimMetricsRequest {
+    int32 port = 1;
+}
+
+service PonSim {
+    rpc SendFrame(PonSimFrame)
+        returns (google.protobuf.Empty) {}
+
+    rpc ReceiveFrames(google.protobuf.Empty)
+        returns (stream PonSimFrame) {}
+
+    rpc GetDeviceInfo(google.protobuf.Empty)
+        returns(PonSimDeviceInfo) {}
+
+    rpc UpdateFlowTable(FlowTable)
+        returns(google.protobuf.Empty) {}
+
+    rpc GetStats(google.protobuf.Empty)
+        returns(PonSimMetrics) {}
+
+}
diff --git a/go/voltha/voltha.proto b/go/voltha/voltha.proto
new file mode 100644
index 0000000..c9e7347
--- /dev/null
+++ b/go/voltha/voltha.proto
@@ -0,0 +1,604 @@
+/*
+ * Top-level Voltha API definition
+ *
+ * For details, see individual definition files.
+ */
+
+syntax = "proto3";
+
+option go_package = "github.com/opencord/voltha-protos/go/voltha";
+
+package voltha;
+
+import "google/api/annotations.proto";
+import "google/protobuf/empty.proto";
+
+import public "voltha_protos/meta.proto";
+import public "voltha_protos/common.proto";
+import public "voltha_protos/health.proto";
+import public "voltha_protos/logical_device.proto";
+import public "voltha_protos/device.proto";
+import public "voltha_protos/adapter.proto";
+import public "voltha_protos/openflow_13.proto";
+
+import "voltha_protos/omci_mib_db.proto";
+import "voltha_protos/omci_alarm_db.proto";
+import "voltha_protos/yang_options.proto";
+
+option java_package = "org.opencord.voltha";
+option java_outer_classname = "VolthaProtos";
+option csharp_namespace = "Opencord.Voltha.Voltha";
+
+message DeviceGroup {
+
+    string id = 1 [(access) = READ_ONLY];
+
+    repeated LogicalDevice logical_devices = 2 [(child_node) = {key: "id"}];
+
+    repeated Device devices = 3 [(child_node) = {key: "id"}];
+}
+
+message DeviceGroups {
+    repeated DeviceGroup items = 1;
+}
+
+
+message AlarmFilterRuleKey {
+    option (yang_child_rule) = MOVE_TO_PARENT_LEVEL;
+
+    enum AlarmFilterRuleKey {
+        id = 0;
+        type = 1;
+        severity = 2;
+        resource_id = 3;
+        category = 4;
+        device_id = 5;
+    }
+}
+
+message AlarmFilterRule {
+    AlarmFilterRuleKey.AlarmFilterRuleKey key = 1;
+    string value = 2;
+}
+message AlarmFilter {
+    string id = 1 [(access) = READ_ONLY];
+
+    repeated AlarmFilterRule rules = 2;
+}
+
+message AlarmFilters {
+    repeated AlarmFilter filters = 1;
+}
+
+message Logging {
+    LogLevel.LogLevel level = 1;
+    string package_name = 2;
+}
+
+// CoreInstance represents a core instance.  It is data held in memory when a core
+// is running.  This data is not persistent.
+message CoreInstance {
+    option (yang_message_rule) = CREATE_BOTH_GROUPING_AND_CONTAINER;
+
+    string instance_id = 1  [(access) = READ_ONLY];
+
+    HealthStatus health = 2 [(child_node) = {}];
+
+}
+
+message CoreInstances {
+    option (yang_message_rule) = CREATE_BOTH_GROUPING_AND_CONTAINER;
+    repeated CoreInstance items = 1;
+}
+
+// Voltha represents the Voltha cluster data.  Each Core instance will hold a subset of
+// the entire cluster. However, some items (e.g. adapters) will be held by all cores
+// for better performance
+message Voltha {
+    option (yang_message_rule) = CREATE_BOTH_GROUPING_AND_CONTAINER;
+
+    string version = 1 [(access) = READ_ONLY];
+
+    repeated Adapter adapters = 2 [(child_node) = {key: "id"}];
+
+    repeated LogicalDevice logical_devices = 3 [(child_node) = {key: "id"}];
+
+    repeated Device devices = 4 [(child_node) = {key: "id"}];
+
+    repeated DeviceType device_types = 5 [(child_node) = {key: "id"}];
+
+    repeated DeviceGroup device_groups = 6 [(child_node) = {key: "id"}];
+
+    repeated AlarmFilter alarm_filters = 7 [(child_node) = {key: "id"}];
+
+    repeated
+        omci.MibDeviceData omci_mib_database = 28
+        [(child_node) = {key: "device_id"}];
+
+    repeated
+        alarm.AlarmDeviceData omci_alarm_database = 29
+        [(child_node) = {key: "device_id"}];
+}
+
+// Device Self Test Response
+message SelfTestResponse {
+    option (yang_child_rule) = MOVE_TO_PARENT_LEVEL;
+
+	enum SelfTestResult  {
+	    SUCCESS = 0;
+	    FAILURE = 1;
+	    NOT_SUPPORTED = 2;
+	    UNKNOWN_ERROR = 3;
+    }
+    SelfTestResult result = 1;
+}
+
+message OfAgentSubscriber {
+    // ID of ofagent instance
+    string ofagent_id = 1;
+
+    // ID of voltha instance to which the ofagent is subscribed
+    string voltha_id = 2;
+}
+
+// Identifies a membership group a Core belongs to
+message Membership {
+    //  Group name
+    string group_name = 1;
+
+    // Unique ID of a container within that group
+    string id = 2;
+}
+
+/*
+ * Voltha APIs
+ *
+ */
+service VolthaService {
+
+    // Get more information on a given physical device
+    rpc UpdateLogLevel(Logging) returns(google.protobuf.Empty) {
+        option (google.api.http) = {
+            get: "/api/v1/logs"
+        };
+    }
+
+    // Get the membership group of a Voltha Core
+    rpc GetMembership(google.protobuf.Empty) returns(Membership) {
+        option (google.api.http) = {
+            get: "/api/v1/membership"
+        };
+    }
+
+    // Set the membership group of a Voltha Core
+    rpc UpdateMembership(Membership) returns(google.protobuf.Empty) {
+        option (google.api.http) = {
+            post: "/api/v1/membership"
+            body: "*"
+        };
+    }
+
+    // Get high level information on the Voltha cluster
+    rpc GetVoltha(google.protobuf.Empty) returns(Voltha) {
+        option (google.api.http) = {
+            get: "/api/v1"
+        };
+    }
+
+    // List all Voltha cluster core instances
+    rpc ListCoreInstances(google.protobuf.Empty) returns(CoreInstances) {
+        option (google.api.http) = {
+            get: "/api/v1/instances"
+        };
+        option (voltha.yang_xml_tag).xml_tag = 'items';
+        option (voltha.yang_xml_tag).list_items_name = 'items';
+    }
+
+    // Get details on a Voltha cluster instance
+    rpc GetCoreInstance(ID) returns(CoreInstance) {
+        option (google.api.http) = {
+            get: "/api/v1/instances/{id}"
+        };
+    }
+
+    // List all active adapters (plugins) in the Voltha cluster
+    rpc ListAdapters(google.protobuf.Empty) returns(Adapters) {
+        option (google.api.http) = {
+            get: "/api/v1/adapters"
+        };
+        option (voltha.yang_xml_tag).xml_tag = 'adapters';
+    }
+
+
+    // List all logical devices managed by the Voltha cluster
+    rpc ListLogicalDevices(google.protobuf.Empty) returns(LogicalDevices) {
+        option (google.api.http) = {
+            get: "/api/v1/logical_devices"
+        };
+        option (voltha.yang_xml_tag).xml_tag = 'logical_devices';
+    }
+
+    // Get additional information on a given logical device
+    rpc GetLogicalDevice(ID) returns(LogicalDevice) {
+        option (google.api.http) = {
+            get: "/api/v1/logical_devices/{id}"
+        };
+    }
+
+    // List ports of a logical device
+    rpc ListLogicalDevicePorts(ID) returns(LogicalPorts) {
+        option (google.api.http) = {
+            get: "/api/v1/logical_devices/{id}/ports"
+        };
+        option (voltha.yang_xml_tag).xml_tag = 'ports';
+    }
+
+    // Gets a logical device port
+    rpc GetLogicalDevicePort(LogicalPortId) returns(LogicalPort) {
+        option (google.api.http) = {
+            get: "/api/v1/logical_devices/{id}/ports/{port_id}"
+        };
+        option (voltha.yang_xml_tag).xml_tag = 'port';
+    }
+
+    // Enables a logical device port
+    rpc EnableLogicalDevicePort(LogicalPortId) returns(google.protobuf.Empty) {
+        option (google.api.http) = {
+            post: "/api/v1/logical_devices/{id}/ports/{port_id}/enable"
+        };
+    }
+
+    // Disables a logical device port
+    rpc DisableLogicalDevicePort(LogicalPortId) returns(google.protobuf.Empty) {
+        option (google.api.http) = {
+            post: "/api/v1/logical_devices/{id}/ports/{port_id}/disable"
+        };
+    }
+
+    // List all flows of a logical device
+    rpc ListLogicalDeviceFlows(ID) returns(openflow_13.Flows) {
+        option (google.api.http) = {
+            get: "/api/v1/logical_devices/{id}/flows"
+        };
+        option (voltha.yang_xml_tag).xml_tag = 'flows';
+        option (voltha.yang_xml_tag).list_items_name = 'items';
+    }
+
+    // Update flow table for logical device
+    rpc UpdateLogicalDeviceFlowTable(openflow_13.FlowTableUpdate)
+            returns(google.protobuf.Empty) {
+        option (google.api.http) = {
+            post: "/api/v1/logical_devices/{id}/flows"
+            body: "*"
+        };
+    }
+
+    // Update meter table for logical device
+    rpc UpdateLogicalDeviceMeterTable(openflow_13.MeterModUpdate)
+            returns(google.protobuf.Empty) {
+        option (google.api.http) = {
+            post: "/api/v1/logical_devices/{id}/meters"
+            body: "*"
+        };
+    }
+
+    // Get all meter stats for logical device
+    rpc GetMeterStatsOfLogicalDevice(ID)
+            returns(openflow_13.MeterStatsReply) {
+        option (google.api.http) = {
+            get: "/api/v1/logical_devices/{id}/meters_stats"
+        };
+    }
+
+    // List all flow groups of a logical device
+    rpc ListLogicalDeviceFlowGroups(ID) returns(openflow_13.FlowGroups) {
+        option (google.api.http) = {
+            get: "/api/v1/logical_devices/{id}/flow_groups"
+        };
+        option (voltha.yang_xml_tag).xml_tag = 'flow_groups';
+        option (voltha.yang_xml_tag).list_items_name = 'items';
+    }
+
+    // Update group table for device
+    rpc UpdateLogicalDeviceFlowGroupTable(openflow_13.FlowGroupTableUpdate)
+            returns(google.protobuf.Empty) {
+        option (google.api.http) = {
+            post: "/api/v1/logical_devices/{id}/flow_groups"
+            body: "*"
+        };
+    }
+
+    // List all physical devices controlled by the Voltha cluster
+    rpc ListDevices(google.protobuf.Empty) returns(Devices) {
+        option (google.api.http) = {
+            get: "/api/v1/devices"
+        };
+        option (voltha.yang_xml_tag).xml_tag = 'devices';
+    }
+
+    // List all physical devices IDs controlled by the Voltha cluster
+    rpc ListDeviceIds(google.protobuf.Empty) returns(IDs) {
+        option (google.api.http) = {
+            get: "/api/v1/deviceids"
+        };
+        option (voltha.yang_xml_tag).xml_tag = 'id';
+        option (voltha.yang_xml_tag).list_items_name = 'items';
+    }
+
+    // Request to a voltha Core to reconcile a set of devices based on their IDs
+    rpc ReconcileDevices(IDs) returns(google.protobuf.Empty) {
+        option (google.api.http) = {
+            post: "/api/v1/deviceids"
+            body: "*"
+        };
+    }
+
+    // Get more information on a given physical device
+    rpc GetDevice(ID) returns(Device) {
+        option (google.api.http) = {
+            get: "/api/v1/devices/{id}"
+        };
+    }
+
+    // Pre-provision a new physical device
+    rpc CreateDevice(Device) returns(Device) {
+        option (google.api.http) = {
+            post: "/api/v1/devices"
+            body: "*"
+        };
+    }
+
+    // Enable a device.  If the device was in pre-provisioned state then it
+    // will transition to ENABLED state.  If it was is DISABLED state then it
+    // will transition to ENABLED state as well.
+    rpc EnableDevice(ID) returns(google.protobuf.Empty) {
+        option (google.api.http) = {
+            post: "/api/v1/devices/{id}/enable"
+        };
+    }
+
+    // Disable a device
+    rpc DisableDevice(ID) returns(google.protobuf.Empty) {
+        option (google.api.http) = {
+            post: "/api/v1/devices/{id}/disable"
+        };
+    }
+
+    // Reboot a device
+    rpc RebootDevice(ID) returns(google.protobuf.Empty) {
+        option (google.api.http) = {
+            post: "/api/v1/devices/{id}/reboot"
+        };
+    }
+
+    // Delete a device
+    rpc DeleteDevice(ID) returns(google.protobuf.Empty) {
+        option (google.api.http) = {
+            delete: "/api/v1/devices/{id}/delete"
+        };
+    }
+
+    // Request an image download to the standby partition
+    // of a device.
+    // Note that the call is expected to be non-blocking.
+    rpc DownloadImage(ImageDownload) returns(OperationResp) {
+        option (google.api.http) = {
+            post: "/api/v1/devices/{id}/image_downloads/{name}"
+            body: "*"
+        };
+    }
+
+    // Get image download status on a device
+    // The request retrieves progress on device and updates db record
+    rpc GetImageDownloadStatus(ImageDownload) returns(ImageDownload) {
+        option (google.api.http) = {
+            get: "/api/v1/devices/{id}/image_downloads/{name}/status"
+        };
+    }
+
+    // Get image download db record
+    rpc GetImageDownload(ImageDownload) returns(ImageDownload) {
+        option (google.api.http) = {
+            get: "/api/v1/devices/{id}/image_downloads/{name}"
+        };
+    }
+
+    // List image download db records for a given device
+    rpc ListImageDownloads(ID) returns(ImageDownloads) {
+        option (google.api.http) = {
+            get: "/api/v1/devices/{id}/image_downloads"
+        };
+    }
+
+    // Cancel an existing image download process on a device
+    rpc CancelImageDownload(ImageDownload) returns(OperationResp) {
+        option (google.api.http) = {
+            delete: "/api/v1/devices/{id}/image_downloads/{name}"
+        };
+    }
+
+    // Activate the specified image at a standby partition
+    // to active partition.
+    // Depending on the device implementation, this call
+    // may or may not cause device reboot.
+    // If no reboot, then a reboot is required to make the
+    // activated image running on device
+    // Note that the call is expected to be non-blocking.
+    rpc ActivateImageUpdate(ImageDownload) returns(OperationResp) {
+        option (google.api.http) = {
+            post: "/api/v1/devices/{id}/image_downloads/{name}/image_update"
+            body: "*"
+        };
+    }
+
+    // Revert the specified image at standby partition
+    // to active partition, and revert to previous image
+    // Depending on the device implementation, this call
+    // may or may not cause device reboot.
+    // If no reboot, then a reboot is required to make the
+    // previous image running on device
+    // Note that the call is expected to be non-blocking.
+    rpc RevertImageUpdate(ImageDownload) returns(OperationResp) {
+        option (google.api.http) = {
+            post: "/api/v1/devices/{id}/image_downloads/{name}/image_revert"
+            body: "*"
+        };
+    }
+
+    // List ports of a device
+    rpc ListDevicePorts(ID) returns(Ports) {
+        option (google.api.http) = {
+            get: "/api/v1/devices/{id}/ports"
+        };
+        option (voltha.yang_xml_tag).xml_tag = 'ports';
+    }
+
+    // List pm config of a device
+    rpc ListDevicePmConfigs(ID) returns(PmConfigs) {
+        option (google.api.http) = {
+            get: "/api/v1/devices/{id}/pm_configs"
+        };
+    }
+
+    // Update the pm config of a device
+    rpc UpdateDevicePmConfigs(voltha.PmConfigs) returns(google.protobuf.Empty) {
+        option (google.api.http) = {
+            post: "/api/v1/devices/{id}/pm_configs"
+            body: "*"
+        };
+    }
+
+    // List all flows of a device
+    rpc ListDeviceFlows(ID) returns(openflow_13.Flows) {
+        option (google.api.http) = {
+            get: "/api/v1/devices/{id}/flows"
+        };
+        option (voltha.yang_xml_tag).xml_tag = 'flows';
+        option (voltha.yang_xml_tag).list_items_name = 'items';
+    }
+
+    // List all flow groups of a device
+    rpc ListDeviceFlowGroups(ID) returns(openflow_13.FlowGroups) {
+        option (google.api.http) = {
+            get: "/api/v1/devices/{id}/flow_groups"
+        };
+        option (voltha.yang_xml_tag).xml_tag = 'flow_groups';
+        option (voltha.yang_xml_tag).list_items_name = 'items';
+    }
+
+    // List device types known to Voltha
+    rpc ListDeviceTypes(google.protobuf.Empty) returns(DeviceTypes) {
+        option (google.api.http) = {
+            get: "/api/v1/device_types"
+        };
+        option (voltha.yang_xml_tag).xml_tag = 'device_types';
+    }
+
+    // Get additional information on a device type
+    rpc GetDeviceType(ID) returns(DeviceType) {
+        option (google.api.http) = {
+            get: "/api/v1/device_types/{id}"
+        };
+    }
+
+    // List all device sharding groups
+    rpc ListDeviceGroups(google.protobuf.Empty) returns(DeviceGroups) {
+        option (google.api.http) = {
+            get: "/api/v1/device_groups"
+        };
+        option (voltha.yang_xml_tag).xml_tag = 'device_groups';
+    }
+
+    // Stream control packets to the dataplane
+    rpc StreamPacketsOut(stream openflow_13.PacketOut)
+        returns(google.protobuf.Empty) {
+        // This does not have an HTTP representation
+    }
+
+    // Receive control packet stream
+    rpc ReceivePacketsIn(google.protobuf.Empty)
+        returns(stream openflow_13.PacketIn) {
+        // This does not have an HTTP representation
+    }
+
+    rpc ReceiveChangeEvents(google.protobuf.Empty)
+        returns(stream openflow_13.ChangeEvent) {
+        // This does not have an HTTP representation
+    }
+
+    // Get additional information on a device group
+    rpc GetDeviceGroup(ID) returns(DeviceGroup) {
+        option (google.api.http) = {
+            get: "/api/v1/device_groups/{id}"
+        };
+    }
+
+    rpc CreateAlarmFilter(AlarmFilter) returns(AlarmFilter) {
+        option (google.api.http) = {
+            post: "/api/v1/alarm_filters"
+            body: "*"
+        };
+    }
+
+    rpc GetAlarmFilter(ID) returns(AlarmFilter) {
+        option (google.api.http) = {
+            get: "/api/v1/alarm_filters/{id}"
+        };
+    }
+
+    rpc UpdateAlarmFilter(AlarmFilter) returns(AlarmFilter) {
+        option (google.api.http) = {
+            put: "/api/v1/alarm_filters/{id}"
+            body: "*"
+        };
+    }
+
+    rpc DeleteAlarmFilter(ID) returns(google.protobuf.Empty) {
+        option (google.api.http) = {
+            delete: "/api/v1/alarm_filters/{id}"
+        };
+    }
+
+    rpc ListAlarmFilters(google.protobuf.Empty) returns(AlarmFilters) {
+        option (google.api.http) = {
+            get: "/api/v1/alarm_filters"
+        };
+    }
+
+    rpc GetImages(ID) returns(Images) {
+        option (google.api.http) = {
+            get: "/api/v1/devices/{id}/images"
+        };
+    }
+
+    rpc SelfTest(ID) returns(SelfTestResponse) {
+        option (google.api.http) = {
+            post: "/api/v1/devices/{id}/self_test"
+        };
+    }
+
+    // OpenOMCI MIB information
+    rpc GetMibDeviceData(ID) returns(omci.MibDeviceData) {
+        option (google.api.http) = {
+            get: "/api/v1/openomci/{id}/mib"
+        };
+    }
+
+    // OpenOMCI ALARM information
+    rpc GetAlarmDeviceData(ID) returns(alarm.AlarmDeviceData) {
+        option (google.api.http) = {
+            get: "/api/v1/openomci/{id}/alarm"
+        };
+    }
+
+    // Simulate an Alarm
+    rpc SimulateAlarm(SimulateAlarmRequest) returns(OperationResp) {
+        option (google.api.http) = {
+            post: "/api/v1/devices/{id}/simulate_larm"
+            body: "*"
+        };
+    }
+    rpc Subscribe (OfAgentSubscriber) returns (OfAgentSubscriber) {
+    }
+}
+