【Network-as-Code】エンジニアに聞きたい！プログラマブルな５Gネットワークがあったら嬉しくない？

# Network as Code を使って、自分のアプリにキャリアの５Gネットワークを組み込んじゃう方法
# はじめに

## Network as Code(NaC)って何？
NOKIAが開発する、通信事業者の4G/5Gネットワークを抽象化して利用できるようにするAPIプラットフォーム。汎用的なプログラミング言語（Python、TypeScript、Javaなど）で、携帯電話のネットワークを利用する端末（スマホ、タブレット、ドローンなど）の位置情報や、そのネットワークの品質に関する情報など、モバイルネットワーク特有の情報を取り込み、自分が作るアプリで利用可能にするもの。NaCのSDKが複雑なモバイルネットワークシステムを抽象化し、専門知識がなくてもネットワークを操作するコードを簡単に書けるようにする。

## モバイルシステムとAPI
　過去、通信事業者が個別に自身のネットワークのAPIをアプリ開発者に解放する動きもあったが、成功したという話はあまり聞こえてこない。一方、Linux Foundationが主導するかたちで発足したCAMARAプロジェクトなど、通信事業者も参画する外部システム向けAPI解放の議論が再燃している。では、なぜ今議論が盛り上がってきたのか。それは通信事業者のネットワークシステム全体のソフトウェア化が進み、オープンなAPIで通信システムの基盤をコントロールできるようになってきているからだろう。
　実際、2010年代半ばに導入されたNFV（Network Function Virtualization）というアーキテクチャにより、巨大なネットワークシステムの仮想化が進んだ。また、5Gではレガシーな通信系プロトコルを廃止し、SBA（Service Based Architecture）が採用され、HTTP/2ベースに統一された。コアネットワークと呼ばれる通信システム装置はRESTベースで通信を行うようになっており、既にAPIが重要な役割を担っている。
　さらに、5Gではユースケースに合わせた最適なネットワーク品質をダイナミックに提供するための仕組み、ネットワークスライシング（スペシャライズドネットワーク）も導入された。これにより、アプリにとって最適な通信品質や通信プランをAPIを介して選択することが可能になる。

## NaCを使うためには
　残念ながら、NaCのSDKを導入しても今使っている携帯電話の通信事業者のネットワークで利用することはできない。NaCと通信事業者の5Gネットワークがインテグレーションされる必要があるためだ。しかし、NOKIAが提供する「SDK for Network as Code」や「Developer Portal」のSandboxを利用するとプログラマブルな５Gネットワークを体験できるので、是非エンジニアの方にチャレンジして欲しい。

## NOKIA Network as Code を使ってみよう！

### NOKIA Developer Portalでユーザー登録する

[NOKIA Developer Portal]('https://developer.networkascode.nokia.io/') にアクセスし、右上の[Login]ボタンからユーザー登録ページに移動。[Register]リンクを押し、フォームを埋めて登録を完了させる。

![スクリーンショット 2024-07-03 2.34.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699739/cf07aeca-c52b-1933-a940-9187c985262e.png)

![スクリーンショット 2024-07-03 2.41.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699739/8c70a2ba-23e4-1735-2660-6b44b3492d26.png)

![スクリーンショット 2024-07-03 2.33.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699739/a9b0fe43-f7d6-ffbe-0750-b325a8934b8a.png)

必須の入力項目として以下の項目を埋め
- Eメールアドレス
- パスワード
- 氏名
- 会社名
- 国名

最後に、マーケティングコミュニケーションに関する同意を確認する。メールを受け取りたくなければ、下段のチェックボックスを選択し断る。

### "Getting Started" で最初のコードを書くまでのステップを確認する

![スクリーンショット 2024-07-03 3.13.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699739/cff90c66-91a3-2209-5619-5f546495aedf.png)

### Dashboardに移り、API Key と Device IDを取得する

![スクリーンショット 2024-07-03 3.13.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699739/d110848a-4245-1967-61d2-6fa0a4dbe920.png)

:::note info
ポイント
 1　[Dashbord](https://developer.networkascode.nokia.io/dashboard)に移る
 2　**My apps** から **API Key**を取得する
 3　**Devices** から デバイスを追加し **DeviceのID**を取得
 
 **API Key** と **Device ID**が取得出来たら「Developer Portal」での作業は完了
:::

### Python環境を構築する

- venvで仮想環境を作る

```zsh
% python -m venv venv
% source venv/bin/activate
```
- pipで **Network as Code** の Pythonモジュールをインストール

``` zsh
% pip install network_as_code
```

## Network as Code のPythonモジュールを使ってコードを書いてみよう


``` main.py
import network_as_code as nac
 
# Network as Code クライアントを生成する

client = nac.NetworkAsCodeClient(
    token="<your-application-key-here>"
)
```
:::note info
ポイント
 - nac.NetworkAsCodeClient()を定義し、NaCのクライアントを生成する
 - __your-application-key-here__ を取得したAPI Keyに置き換える

:::

``` main.py
my_device = client.devices.get(
    "<your-device-id>@testcsp.net",
    ipv4_address=DeviceIpv4Addr(
        public_address="233.252.0.2", private_address="192.0.2.25", public_port=80
    ),
    ipv6_address="2001:db8:1234:5678:9abc:def0:fedc:ba98",
    phone_number="36721601234567",
)
```
:::note info
ポイント
- このデバイスはSandbox内で利用される擬似端末
- __your-device-id__ をDashboardで取得した**Device ID**に置き換える
- IPアドレスなどは、とりあえずそのままでOK
:::

## NaCのライブラリを使って位置情報を取得しGoogle　Mapに表示するコードを書いてみる

``` main.py
import gmplot  # type: ignore
import network_as_code as nac  # type: ignore
from network_as_code.models.device import DeviceIpv4Addr  # type: ignore

# NaCのクライアントを生成
client = nac.NetworkAsCodeClient(
    token="<your-application-key-here>" #取得したAPI keyに置き換える
)

# デバイスを設定（ここでは擬似端末）
my_device = client.devices.get(
    "<your-device-id>@testcsp.net",   #取得したDevice IDに置き換える
    ipv4_address=DeviceIpv4Addr(
        public_address="233.252.0.2", private_address="192.0.2.25", public_port=80
    ),
    ipv6_address="2001:db8:1234:5678:9abc:def0:fedc:ba98",
    phone_number="36721601234567",
)

# 位置情報を取得する (3,600秒で設定)
location = my_device.location(max_age=3600)

latitude = location.latitude     # 緯度
longitude = location.longitude   # 経度 

# Google Maps API Key
gmapi_key = "<Google Map API Key>" #取得したGoogle MapのAPI　Keyに置き換える

# 地図のズームレベル
zoom_level = 15

# Googleマップのセンターポイント
gmap = gmplot.GoogleMapPlotter(latitude, longitude, zoom_level, apikey=gmapi_key)

# Google　Map上にマーカーを配置
gmap.marker(latitude, longitude, color="red")

# map.htmlとして保存する
gmap.draw("map.html")

```

:::note info
ポイント
- my_device.location(max_age=3600)で緯度・経度情報を取得
- 位置情報取得の引数（max_age）は必須。位置情報取得にかかる最大時間を指定する。指定がないときはデフォルトの60秒に設定される
- [Google Map API Key](https://developers.google.com/maps/premium/apikey/geocoding-apikey?hl=ja) からGoogle Map用のAPI Keyを取得（登録時にクレジットカード情報が必要）
:::

### map.htmlのイメージ
![スクリーンショット 2024-07-03 11.50.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699739/99ad9837-44f0-f850-e33c-13b3b90231c2.png)

# まとめ
- 今回は位置情報を取得するだけAPIの紹介でしたが、その他に以下のようなAPIもサポートしています
    - Quality-of-service on Demand (QoD) ‐ アプリに最適なQoSプランを適用する
    - Network Insights - 端末があるエリアでのネットワークの輻輳状態を確認する
    - Device Status - 端末のコネクティビティ状態を確認する
    - Specialized Networks - ユースケースに適したネットワークスライスを選択する
- 既に海外の通信事業者で導入するところも出てきている。もう少しすると、モバイルネットワークを自分のアプリに組み込むような世界が来るかもしれない！ 😃