Initial check in for swift rest runtime.

This commit is contained in:
Alva Bandy 2017-10-11 22:26:10 -07:00
Родитель 9616631b03
Коммит ad76dcf864
23 изменённых файлов: 1839 добавлений и 0 удалений

9
.gitmodules поставляемый Normal file
Просмотреть файл

@ -0,0 +1,9 @@
[submodule "Alamofire"]
path = Alamofire
url = https://github.com/Alamofire/Alamofire.git
[submodule "SwiftyJSON"]
path = SwiftyJSON
url = https://github.com/SwiftyJSON/SwiftyJSON.git
[submodule "RxSwift"]
path = RxSwift
url = https://github.com/ReactiveX/RxSwift.git

1
Alamofire Submodule

@ -0,0 +1 @@
Subproject commit 6d9b4885fbd7837861c5216d2ae4a1131e599f30

34
Package.resolved Normal file
Просмотреть файл

@ -0,0 +1,34 @@
{
"object": {
"pins": [
{
"package": "Alamofire",
"repositoryURL": "https://github.com/Alamofire/Alamofire.git",
"state": {
"branch": null,
"revision": "b8995447518fd57af14c88a47f27434a16f60403",
"version": "4.5.1"
}
},
{
"package": "RxSwift",
"repositoryURL": "https://github.com/ReactiveX/RxSwift.git",
"state": {
"branch": null,
"revision": "80de9622b9bd1dca409b0e66e3ccc418676e571e",
"version": "3.6.1"
}
},
{
"package": "SwiftyJSON",
"repositoryURL": "https://github.com/SwiftyJSON/SwiftyJSON.git",
"state": {
"branch": null,
"revision": "dadbfcffd5f51e2b488a26e83f188d96755e5393",
"version": "3.1.4"
}
}
]
},
"version": 1
}

31
Package.swift Normal file
Просмотреть файл

@ -0,0 +1,31 @@
// swift-tools-version:4.0
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "azureSwiftRuntime",
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "azureSwiftRuntime",
targets: ["azureSwiftRuntime"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
.package(url: "https://github.com/Alamofire/Alamofire.git", from: "4.0.10"),
.package(url: "https://github.com/ReactiveX/RxSwift.git", from: "3.4.2"),
.package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", from: "3.1.4"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(
name: "azureSwiftRuntime",
dependencies: ["Alamofire", "RxSwift", "SwiftyJSON"]),
.testTarget(
name: "azureSwiftRuntimeTests",
dependencies: ["azureSwiftRuntime"]),
]
)

1
RxSwift Submodule

@ -0,0 +1 @@
Subproject commit 4995928ca47fd81e89f3bb821c5ac78c1ac286d1

Просмотреть файл

@ -0,0 +1,55 @@
//
// AuthData.swift
// azureSwiftRuntimePackageDescription
//
// Created by Alva D Bandy on 10/4/17.
//
import SwiftyJSON
public class AuthData {
let grantType: String = "client_credentials"
let resource: String = "https://management.core.windows.net/"
var authURL: String
var clientCredentials: String
var clientSecret: String
var subscription: String
var tenant: String
var accessToken: String? = nil
var refreshToken: String? = nil
var baseURL: String
init(authURL: String,
clientCredentials: String,
clientSecret: String,
subscription: String,
tenant: String,
baseURL: String) {
self.authURL = authURL
self.clientCredentials = clientCredentials
self.clientSecret = clientSecret
self.subscription = subscription
self.tenant = tenant
self.baseURL = baseURL
}
public static func load(location: String) -> AuthData? {
guard let content = try? String(contentsOfFile: location, encoding: String.Encoding.utf8) else {
return nil
}
guard let dataFromString = content.data(using: .utf8, allowLossyConversion: false) else {
return nil
}
guard let jsonContent = try? JSON(data: dataFromString) else {
return nil;
}
return AuthData(authURL: jsonContent["authURL"].string!,
clientCredentials: jsonContent["client"].string!,
clientSecret: jsonContent["key"].string!,
subscription: jsonContent["subscription"].string!,
tenant: jsonContent["tenant"].string!,
baseURL: jsonContent["baseURL"].string!)
}
}

Просмотреть файл

@ -0,0 +1,35 @@
import Alamofire
import RxSwift
class AzureAuthticate {
var authData: AuthData;
init(authData: AuthData) {
self.authData = authData
}
func connect() -> Observable<Void> {
return Observable<Void>.create({observable in
let parameters: Parameters = ["grant_type": self.authData.grantType,
"client_id": self.authData.clientCredentials,
"client_secret": self.authData.clientSecret,
"resource": self.authData.resource]
let request = Alamofire.request("\(self.authData.authURL)\(self.authData.tenant)/oauth2/token",
method: .post, parameters: parameters).responseJSON(completionHandler: { response in
if response.result.isSuccess {
if let data = response.result.value as? [String: Any] {
self.authData.accessToken = data["access_token"] as? String;
observable.onNext(Void())
}else {
observable.onError(RestfulError("test"));
}
}
})
return Disposables.create {
request.cancel()
}
})
}
}

Просмотреть файл

@ -0,0 +1,39 @@
//
// RestDelete.swift
// azureSwiftRuntimePackageDescription
//
// Created by Alva D Bandy on 10/10/17.
//
import Alamofire
import RxSwift
import SwiftyJSON
public final class RestDelete: Restful {
let url: String
let helper: AzureRestHelper
init(helper: AzureRestHelper, url: String) {
self.helper = helper
self.url = url;
}
public func call() -> Observable<JSON?> {
let headers = helper.getHeadersWithAuthAndCustomSet()
return Observable<JSON?>.create({observable in
let request = Alamofire.request(self.url, method: .delete, headers: headers)
.responseData(completionHandler: { response in
switch response.result {
case .success(let data):
observable.onNext(JSON(["deleted": true]))
case .failure(let error):
observable.onError(error);
}
})
return Disposables.create {
request.cancel()
}
})
}
}

Просмотреть файл

@ -0,0 +1,37 @@
//
// RestGet.swift
// azureSwiftRuntimePackageDescription
//
// Created by Alva D Bandy on 10/4/17.
//
import Alamofire
import RxSwift
import SwiftyJSON
public final class RestGet: Restful {
let url: String
let helper: AzureRestHelper
init(helper: AzureRestHelper, url: String) {
self.url = url
self.helper = helper
}
public func call() -> Observable<JSON?> {
let headers = self.helper.getHeadersWithAuthAndCustomSet()
return Observable<JSON?>.create({observable in
let request = Alamofire.request(self.url, method: .get, headers: headers)
.responseJSON(completionHandler: { response in
if let data = response.result.value as? [String: Any] {
observable.onNext(JSON(data))
}else {
observable.onError(RestfulError("test"));
}
})
return Disposables.create {
request.cancel()
}
})
}
}

Просмотреть файл

@ -0,0 +1,40 @@
//
// RestPost.swift
// azureSwiftRuntimePackageDescription
//
// Created by Alva D Bandy on 10/9/17.
//
import Alamofire
import RxSwift
import SwiftyJSON
public final class RestPost: Restful {
let url: String
let data: [String: Any]
let helper: AzureRestHelper
init(helper: AzureRestHelper, url:String, data: [String: Any]) {
self.helper = helper
self.url = url;
self.data = data;
}
public func call() -> Observable<JSON?> {
let headers = helper.getHeadersWithAuthAndCustomSet()
return Observable<JSON?>.create({observable in
let request = Alamofire.request(self.url, method: .post, parameters: self.data, encoding: JSONEncoding.default, headers: headers)
.responseJSON(completionHandler: { response in
if let data = response.result.value as? [String: Any] {
observable.onNext(JSON(data))
}else {
observable.onError(RestfulError("test"));
}
})
return Disposables.create {
request.cancel()
}
})
}
}

Просмотреть файл

@ -0,0 +1,40 @@
//
// RestGet.swift
// azureSwiftRuntimePackageDescription
//
// Created by Alva D Bandy on 10/4/17.
//
import Alamofire
import RxSwift
import SwiftyJSON
public final class RestPut: Restful {
let url: String
let data: [String: Any]
let helper: AzureRestHelper
init(helper: AzureRestHelper, url: String, data: [String: Any]) {
self.helper = helper;
self.url = url;
self.data = data;
}
public func call() -> Observable<JSON?> {
let headers = helper.getHeadersWithAuthAndCustomSet()
return Observable<JSON?>.create({observable in
let request = Alamofire.request(self.url, method: .put, parameters: self.data, encoding: JSONEncoding.default, headers: headers)
.responseJSON(completionHandler: { response in
if let data = response.result.value as? [String: Any] {
observable.onNext(JSON(data))
}else {
observable.onError(RestfulError("test"));
}
})
return Disposables.create {
request.cancel()
}
})
}
}

Просмотреть файл

@ -0,0 +1,13 @@
//
// Restful.swift
// azureSwiftRuntimePackageDescription
//
// Created by Alva D Bandy on 10/4/17.
//
import SwiftyJSON
import RxSwift
public protocol Restful {
func call() -> Observable<JSON?>
}

Просмотреть файл

@ -0,0 +1,14 @@
//
// RestfulError.swift
// azureSwiftRuntimePackageDescription
//
// Created by Alva D Bandy on 10/7/17.
//
class RestfulError : Error {
var description: String
init(_ description: String) {
self.description = description
}
}

Просмотреть файл

@ -0,0 +1,66 @@
//
// RestfulFactory.swift
// azureSwiftRuntimePackageDescription
//
// Created by Alva D Bandy on 10/4/17.
//
import RxSwift
import Alamofire
public protocol AzureRestHelper {
func getHeadersWithAuthAndCustomSet() -> HTTPHeaders
}
public final class RestfulFactory : AzureRestHelper {
var azureAuthenticate: AzureAuthticate
var beforeHeaderFunc: ((HTTPHeaders) -> ())? = nil
var subcriptionId: String {
return self.azureAuthenticate.authData.subscription
}
var baseURL: String {
return self.azureAuthenticate.authData.baseURL
}
init(azureAuthenticate: AzureAuthticate) {
self.azureAuthenticate = azureAuthenticate;
}
convenience init() throws {
guard let authData = AuthData.load(location: "/Users/alvab/myauth.azureAuth.json") else {
throw RestfulError("Unable to load auth file")
}
self.init(azureAuthenticate: AzureAuthticate(authData: authData));
}
public func connect() -> Observable<Void> {
return self.azureAuthenticate.connect()
}
public func getHeadersWithAuthAndCustomSet() -> HTTPHeaders {
var headers = HTTPHeaders()
if beforeHeaderFunc != nil {
beforeHeaderFunc!(headers)
}
headers["Authorization"] = "Bearer \(self.azureAuthenticate.authData.accessToken!)"
return headers;
}
public func getCall(verb: RestfulVerb) -> Restful {
switch(verb) {
case .Get(let url):
return RestGet(helper: self, url: url)
case .Put(let url, let data):
return RestPut(helper: self, url: url, data: data)
case .Post(let url, let data):
return RestPost(helper: self, url: url, data: data)
case .Patch(let url, let data):
return RestPost(helper: self, url: url, data: data)
case .Delete(let url):
return RestDelete(helper: self, url: url)
}
}
}

Просмотреть файл

@ -0,0 +1,14 @@
//
// RestfulVerb.swift
// azureSwiftRuntimePackageDescription
//
// Created by Alva D Bandy on 10/4/17.
//
public enum RestfulVerb {
case Get(url: String)
case Put (url: String, data: [String: Any])
case Post (url: String, data: [String: Any])
case Patch (url: String, data: [String: Any])
case Delete (url: String)
}

1
SwiftyJSON Submodule

@ -0,0 +1 @@
Subproject commit e1b9090415109b61b6f16b97c75399ed1bec5e62

Просмотреть файл

@ -0,0 +1,81 @@
import XCTest
import RxSwift
import RxBlocking
import SwiftyJSON
@testable import azureSwiftRuntime
class azureSwiftRuntimeTests: XCTestCase {
func testExample() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct
// results.
let myName = "swiftResourceGroup4"
guard let restFactory = try? RestfulFactory() else {
return;
}
try! restFactory.connect().toBlocking().first()
let restGet = restFactory.getCall(
verb: .Get(url: "\(restFactory.baseURL)subscriptions/\(restFactory.subcriptionId)/resourcegroups?api-version=2016-06-01"))
let obs = restGet.call()
guard let allResource = try! obs.toBlocking().first() else {
return
}
if let resourcesArray = allResource!["value"].array {
var resource = resourcesArray[0]
let id = resource["id"].string!
let name = resource["name"].string!
let index = id.endIndex
let sIndex = id.index(id.startIndex, offsetBy: 1)
let idPart = String(describing: id[sIndex..<index])
let restGet1 = restFactory.getCall(
verb: .Get(url: "\(restFactory.baseURL)\(idPart)?api-version=2016-06-01"))
let obs2 = restGet1.call()
guard let myResource = try! obs2.toBlocking().first() else {
return
}
print(myResource as Any)
let newId = idPart.replacingOccurrences(of: name, with: myName)
var newResourceGroup = [String: Any]()
newResourceGroup["name"] = myName;
newResourceGroup["location"] = "westus"
let restPut = restFactory.getCall(
verb: .Put(url: "\(restFactory.baseURL)\(newId)?api-version=2016-06-01", data: newResourceGroup))
let obs = restPut.call()
guard let madeResource = try! obs.toBlocking().first() else {
return
}
print(madeResource as Any);
let exportTemplateResource = ["resources": ["*"]]
let restPost = restFactory.getCall(
verb: .Post(url: "\(restFactory.baseURL)\(newId)/exportTemplate?api-version=2016-09-01", data: exportTemplateResource))
let postObs = restPost.call()
guard let postResource = try! postObs.toBlocking().first() else {
return
}
print(postResource as Any);
let restDelete = restFactory.getCall(
verb: .Delete(url: "\(restFactory.baseURL)\(newId)?api-version=2016-06-01"))
let deleteObs = restDelete.call()
guard let deleteResource = try? deleteObs.toBlocking().first() else {
return
}
print("Deleted");
}
//XCTAssertEqual(azureSwiftRuntime().text, "Hello, World!")
}
static var allTests = [
("testExample", testExample),
]
}

Просмотреть файл

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

Просмотреть файл

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

Просмотреть файл

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "azureSwiftRuntime::azureSwiftRuntime"
BuildableName = "azureSwiftRuntime.framework"
BlueprintName = "azureSwiftRuntime"
ReferencedContainer = "container:azureSwiftRuntime.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "azureSwiftRuntime::azureSwiftRuntimeTests"
BuildableName = "azureSwiftRuntimeTests.xctest"
BlueprintName = "azureSwiftRuntimeTests"
ReferencedContainer = "container:azureSwiftRuntime.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "azureSwiftRuntime::azureSwiftRuntime"
BuildableName = "azureSwiftRuntime.framework"
BlueprintName = "azureSwiftRuntime"
ReferencedContainer = "container:azureSwiftRuntime.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

Просмотреть файл

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>azureSwiftRuntime-Package.xcscheme</key>
<dict></dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict></dict>
</dict>
</plist>