Skip to content

Commit

Permalink
Add Azure Programmable Connectivity dataplane APIs (#26922)
Browse files Browse the repository at this point in the history
* Move initial work over from private repo

* Add some more TODOs

* Fix location API - Remove MaxAge parameter

* Resolve TODOs

* fix pipeline issues

* markups

* markups

* markups

* make extenrla id also consistant with strucutre

* fix formatting

* Add Device to SimSwapVerifyRequest, and make IP addresses optional in LocationVerifyRequest

* change the scope URL to https://management.azure.com/.default

* change scopein openapi.json to https://management.azure.com/.default as well

* Adding python config to tspconfig.yaml

* change endpoint casing and fix formatting

* update examples

* fix typo

* add c sharp

* rename some variables because .net generatiopn is complaining about it. Request>content and response>Result

* some more replaces

* Fix single word classes:

Single word class names are too generic and have high chance of collision with BCL types or types from other libraries

* try adding veriosning

* try adding ver

* fix date

* replace NetworkDevice >>> NetworkRetrieveResult

* Typespec validation pass

* replace older version with current one

* Further pipeline fixing

* use proper nouns, and do easy changes

* camel case

* replace *Interface with base path of the API

* Retrieve>Retrieval

* blankline

* rename some variables

* new lines prettier

* number interface > number verification

* new lines

* blank lines

* Add deprecation notice

* remove enums and add response header

* remove devicenetworkidentifier, as it's duplicate, change long/latitude to doubles

* Make ApcError an extension of Azure.Core.Foundations.Error

* Number verification updates for frontend auth

* ImplDocument number verification in typespec

* Remove python and .net sdk configuration, pending resolution of namespace discussions

* Update date of api version

* Some pipeline wrangling

* Remove NumberVerification retrieval APIs as they will not be implemented for public preview; add suppression of ValidResponseCodeRequired

* Add back Python SDK after fixes to autogen

* Improve docstrings, try to localize suppressions

---------

Co-authored-by: Jamie Ford <[email protected]>
Co-authored-by: Ella Bridgett-Tomkinson <[email protected]>
Co-authored-by: Aron Hegedus <[email protected]>
  • Loading branch information
4 people authored Feb 13, 2024
1 parent 0c885c1 commit 7488ab7
Show file tree
Hide file tree
Showing 23 changed files with 1,864 additions and 0 deletions.
2 changes: 2 additions & 0 deletions custom-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ aods
aosm
apac
apacheavro
apcgatewayapi
api's
apim
apimanagement
Expand Down Expand Up @@ -422,6 +423,7 @@ bzip
cacerts
cadl
calculatebaseline
camara
canadacentral
canadaeast
canceldelete
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import "@typespec/rest";
import "@typespec/versioning";
import "@azure-tools/typespec-azure-core";

using TypeSpec.Http;
using TypeSpec.Rest;
using TypeSpec.Versioning;
using Azure.Core;
using Azure.Core.Traits;

namespace Azure.ProgrammableConnectivity;

alias ServiceTraits = NoRepeatableRequests &
NoConditionalRequests &
SupportsClientRequestId &
RequestHeadersTrait<ApcGatewayIdHeader> &
// Note that ResponseHeadersTrait is overridden in number operations
// If you modify this, you must also modify it in the number operations.
ResponseHeadersTrait<RequestIdResponseHeader>;

// alias Operations = Azure.Core.ResourceOperations<ServiceTraits, ApcErrorResponse>;
alias Operations = Azure.Core.ResourceOperations<
ServiceTraits,
Azure.Core.Foundations.ErrorResponse
>;

@doc("Header to identify APC Gateway resource.")
model ApcGatewayIdHeader {
@doc("The identifier of the APC Gateway resource which should handle this request.")
@header("apc-gateway-id")
apcGatewayId: string;
}

@doc("Identifier for the network to be queried")
model NetworkIdentifier {
@doc("The type of identifier for the network. one of: 'IPv4', 'IPv6', 'NetworkCode'")
identifierType: string;

@doc("""
The network identifier, based on the identifierType: an IPv4 address, and IPv6 address, or a Network Code.
A Network Code may be obtained from APC documentation or from the APC /Network:retrieve endpoint.
""")
identifier: string;
}

@doc("The phone number of the device.")
model PhoneNumberModel {
@doc("Phone number in E.164 format (starting with country code), and optionally prefixed with '+'")
@pattern("^\\+?[0-9]{5,15}$")
phoneNumber?: string;
}

@doc("The network access ID/external ID of the device")
model NetworkAccessIdentifierModel {
@doc("External identifier or network access identifier of the device")
networkAccessIdentifier?: string;
}

@error
@doc("A custom error response for APC.")
model ApcErrorResponse {
@doc("Error returned by APC")
error: ApcError;

@header("x-ms-error-code")
@doc("String error code indicating what went wrong.")
errorCode?: string;
}

@doc("A custom error for APC.")
model ApcError {
...Azure.Core.Foundations.Error;

@doc("The consent URL in case of a consent failure")
consentUrl?: url;
}

@doc("IPv4 address and port of the device")
model Ipv4AddressModel {
@doc("The Ipv4 address")
ipv4Address?: Ipv4Address;
}

@doc("IPv4 address and port of the device")
model Ipv6AddressModel {
@doc("The Ipv6 address")
ipv6Address?: Ipv6Address;
}

@doc("IPv4 device indicator")
model Ipv4Address {
@doc("An IPv4 address. This may be specified as an exact address, or as a subnet in CIDR notation.")
ipv4: string;

@doc("User equipment port.")
port: int32;
}

@doc("IPv6 device indicator")
model Ipv6Address {
@doc("An IPv6 address. This may be specified as an exact address, or as a subnet in CIDR notation.")
ipv6: string;

@doc("User equipment port.")
port: int32;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import "./common.tsp";

using TypeSpec.Http;
using TypeSpec.Rest;
using TypeSpec.Versioning;
using Azure.Core;

namespace Azure.ProgrammableConnectivity;

/// Interfaces

interface DeviceLocation {
@doc("Verifies whether a device is within a specified location area, defined as an accuracy (radius) around a point, specified by longitude and latitude.")
verify is Operations.ResourceAction<
DeviceLocationEndpoint,
DeviceLocationVerificationContent,
DeviceLocationVerificationResult
>;
}

/// Endpoints

@resource("device-location")
@doc("Static endpoint to access the Device Location API family.")
model DeviceLocationEndpoint {
@key
@doc("Static endpoint")
@visibility("read")
location: "location";
}

/// Request models

@doc("Request to verify Location")
model DeviceLocationVerificationContent {
@doc("Network to query for this device, or device information to enable network routing.")
networkIdentifier: NetworkIdentifier;

@doc("Latitude of location to be verified")
@minValue(-90)
@maxValue(90)
latitude: float64;

@doc("Longitude of location to be verified")
@minValue(-180)
@maxValue(180)
longitude: float64;

@doc("Accuracy expected for location verification in kilometers")
@minValue(2)
@maxValue(100)
accuracy: int32;

@doc("The device to find the location for. Exactly one of Network Access Code, Phone Number, IPv4 address, or IPv6 address")
device: LocationDevice;
}

/// Response models

@doc("Response verifying location")
model DeviceLocationVerificationResult {
@doc("True if the location is in the specified area, False otherwise")
verificationResult: boolean;
}

/// Common models

// LocationDevice represents a Device as required by the Location API. The APC team aims
// to drive commonisation of the underlying CAMARA APIs so that all APIs can share a common Device
// model in future.
@doc("Device information needed by operator to provide location information. Include exactly one of these properties to identify your device.")
model LocationDevice {
...NetworkAccessIdentifierModel;
...PhoneNumberModel;
...Ipv4AddressModel;
...Ipv6AddressModel;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import "./common.tsp";

using TypeSpec.Http;
using TypeSpec.Rest;
using TypeSpec.Versioning;
using Azure.Core;
using Azure.Core.Traits;

namespace Azure.ProgrammableConnectivity;

/// Interfaces

interface DeviceNetwork {
@doc("Retrieves the network a given device is on. Returns network in a networkCode format that can be used for other APIs.")
retrieve is Operations.ResourceAction<
DeviceNetworkRetrievalEndpoint,
NetworkIdentifier,
NetworkRetrievalResult
>;
}

/// Endpoints

@resource("device-network")
@doc("Static endpoint to access the Device Network API family.")
model DeviceNetworkRetrievalEndpoint {
@key
@doc("Static endpoint")
@visibility("read")
network: "network";
}

/// Common models

@doc("The network that the device is on.")
model NetworkRetrievalResult {
@pattern("[a-z0-9-]+$")
@doc("The identifier for the network. This can be used as the networkIdentifier for the service APIs.")
networkCode: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import "./common.tsp";

using TypeSpec.Http;
using TypeSpec.Rest;
using TypeSpec.Versioning;
using Azure.Core;
using Azure.Core.Traits;

namespace Azure.ProgrammableConnectivity;

/// Interfaces

@doc("""
Number operations include Frontend Authentication.
Users first make a call to the endpoint /Number:verify, which returns a redirect to the device's
Network. This is followed by the device to authenticate directly with the Network. The Network
responds with a token and a redirect. This token can be exchanged with APC for a code.
Users make a second call to the endpoint /Number:verify including the code. The code is used
to verify the device number. The second response is a 200 containing the result of the query.
For more information on the steps required to use Number Verificaiton, see the APC documentation.
""")
interface NumberVerification {
#suppress "@azure-tools/typespec-azure-core/no-response-body" "302 redirect has no response body"
@doc("Verifies the phone number (MSISDN) associated with a device. As part of the frontend authorization flow, the device is redirected to the operator network to authenticate directly.")
@sharedRoute
@action("verify")
verifyWithoutCode is Operations.ResourceAction<
NumberVerificationEndpoint,
NumberVerificationWithoutCodeContent,
TypeSpec.Http.Response<302> & {},
TraitOverride<ResponseHeadersTrait<{
@header location: string;
} & RequestIdResponseHeader>>
>;

@doc("Verifies the phone number (MSISDN) associated with a device.")
@sharedRoute
@action("verify")
verifyWithCode is Operations.ResourceAction<
NumberVerificationEndpoint,
NumberVerificationWithCodeContent,
NumberVerificationResult
>;
}

/// Endpoints

@resource("number-verification")
@doc("Static endpoint to access Number Verification API family")
model NumberVerificationEndpoint {
@key
@doc("Static endpoint")
@visibility("read")
number: "number";
}

/// Request models

@doc("Request to verify number of device - first call")
model NumberVerificationWithoutCodeContent {
@doc("Identifier for the network to query for this device.")
networkIdentifier: NetworkIdentifier;

...NumberDevice;
}

@doc("Request to verify number of device - second call")
model NumberVerificationWithCodeContent {
@doc("Identifier for the network to query for this device.")
networkIdentifier: NetworkIdentifier;

...NumberDevice;

@doc("The code provided by APC in exchange for the operator code.")
apcCode: string;
}

/// Response models

@doc("Response verifying number of device")
model NumberVerificationResult {
@doc("True if number if the phone number matches the device, False otherwise")
verificationResult: boolean;
}

/// Common models

// NumberDevice represents a Device as required by the Number Verification API. The APC team aims
// to drive commonisation of the underlying CAMARA APIs so that all APIs can share a common Device
// model in future.
@doc("Device information to verify phone number. Include exactly one form of phone number.")
model NumberDevice {
...PhoneNumberModel;

@doc("Hashed phone number. SHA-256 (in hexadecimal representation) of the mobile phone number in **E.164 format (starting with country code)**. Optionally prefixed with '+'.")
hashedPhoneNumber?: string;
}
Loading

0 comments on commit 7488ab7

Please sign in to comment.