Skip to content

Commit ca56259

Browse files
committed
Add fixes from apache#139
1 parent 6073686 commit ca56259

File tree

16 files changed

+635
-2
lines changed

16 files changed

+635
-2
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ deploy:
4747
branch: master
4848
repo: apache/openwhisk-runtime-swift
4949
- provider: script
50-
script: "./tools/travis/publish.sh openwhisk 5.1 nightly && ./tools/travis/publish.sh openwhisk 5.3 nightly"
50+
script: "./tools/travis/publish.sh openwhisk 5.1 nightly && ./tools/travis/publish.sh openwhisk 5.3 nightly && ./tools/travis/publish.sh openwhisk 5.4 nightly"
5151
on:
5252
branch: master
5353
repo: apache/openwhisk-runtime-swift

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
- [Swift 4.2 CHANGELOG.md](core/swift42Action/CHANGELOG.md)
2727
- [Swift 5.1 CHANGELOG.md](core/swift51Action/CHANGELOG.md)
2828
- [Swift 5.3 CHANGELOG.md](core/swift53Action/CHANGELOG.md)
29+
- [Swift 5.4 CHANGELOG.md](core/swift54Action/CHANGELOG.md)
2930

3031
## Quick Swift Action
3132
### Simple swift action hello.swift

ansible/files/runtimes.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,20 @@
7171
"attachmentName": "codefile",
7272
"attachmentType": "text/plain"
7373
}
74+
},
75+
{
76+
"kind": "swift:5.4",
77+
"default": false,
78+
"image": {
79+
"prefix": "testing",
80+
"name": "action-swift-v5.4",
81+
"tag": "latest"
82+
},
83+
"deprecated": false,
84+
"attached": {
85+
"attachmentName": "codefile",
86+
"attachmentType": "text/plain"
87+
}
7488
}
7589
]
7690
},

core/swift54Action/CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!--
2+
#
3+
# Licensed to the Apache Software Foundation (ASF) under one or more
4+
# contributor license agreements. See the NOTICE file distributed with
5+
# this work for additional information regarding copyright ownership.
6+
# The ASF licenses this file to You under the Apache License, Version 2.0
7+
# (the "License"); you may not use this file except in compliance with
8+
# the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
-->
19+
20+
# Apache OpenWhisk Swift 5.4 Runtime Container
21+
22+
## 1.16.0
23+
- Initial Release

core/swift54Action/Dockerfile

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one or more
3+
# contributor license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright ownership.
5+
# The ASF licenses this file to You under the Apache License, Version 2.0
6+
# (the "License"); you may not use this file except in compliance with
7+
# the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
# build go proxy from source
19+
FROM golang:1.15 AS builder_source
20+
ARG GO_PROXY_GITHUB_USER=apache
21+
ARG GO_PROXY_GITHUB_BRANCH=master
22+
RUN git clone --branch ${GO_PROXY_GITHUB_BRANCH} \
23+
https://github.com/${GO_PROXY_GITHUB_USER}/openwhisk-runtime-go /src ;\
24+
cd /src ; env GO111MODULE=on CGO_ENABLED=0 go build main/proxy.go && \
25+
mv proxy /bin/proxy
26+
27+
# or build it from a release
28+
FROM golang:1.15 AS builder_release
29+
30+
RUN curl -sL \
31+
https://github.com/apache/openwhisk-runtime-go/archive/{$GO_PROXY_RELEASE_VERSION}.tar.gz\
32+
| tar xzf -\
33+
&& cd openwhisk-runtime-go-*/main\
34+
&& GO111MODULE=on go build -o /bin/proxy
35+
36+
FROM swift:5.4
37+
38+
# select the builder to use
39+
ARG GO_PROXY_BUILD_FROM=release
40+
41+
RUN rm -rf /var/lib/apt/lists/* && apt-get clean && apt-get -qq update \
42+
&& apt-get install -y --no-install-recommends locales python3 vim libssl-dev libicu-dev \
43+
&& rm -rf /var/lib/apt/lists/* \
44+
&& locale-gen en_US.UTF-8
45+
46+
ENV LANG="en_US.UTF-8" \
47+
LANGUAGE="en_US:en" \
48+
LC_ALL="en_US.UTF-8"
49+
50+
RUN mkdir -p /swiftAction
51+
WORKDIR /swiftAction
52+
53+
COPY --from=builder_source /bin/proxy /bin/proxy_source
54+
COPY --from=builder_release /bin/proxy /bin/proxy_release
55+
RUN mv /bin/proxy_${GO_PROXY_BUILD_FROM} /bin/proxy
56+
ADD swiftbuild.py /bin/compile
57+
ADD swiftbuild.py.launcher.swift /bin/compile.launcher.swift
58+
COPY _Whisk.swift /swiftAction/Sources/
59+
COPY Package.swift /swiftAction/
60+
COPY swiftbuildandlink.sh /swiftAction/
61+
COPY main.swift /swiftAction/Sources/
62+
RUN swift build -c release; \
63+
touch /swiftAction/Sources/main.swift; \
64+
rm /swiftAction/.build/release/Action
65+
66+
ENV OW_COMPILER=/bin/compile
67+
ENTRYPOINT [ "/bin/proxy" ]

core/swift54Action/Package.swift

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// swift-tools-version:4.2
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
/*
5+
* Licensed to the Apache Software Foundation (ASF) under one or more
6+
* contributor license agreements. See the NOTICE file distributed with
7+
* this work for additional information regarding copyright ownership.
8+
* The ASF licenses this file to You under the Apache License, Version 2.0
9+
* (the "License"); you may not use this file except in compliance with
10+
* the License. You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*/
20+
21+
import PackageDescription
22+
23+
let package = Package(
24+
name: "Action",
25+
products: [
26+
.executable(
27+
name: "Action",
28+
targets: ["Action"]
29+
)
30+
],
31+
targets: [
32+
.target(
33+
name: "Action",
34+
path: "."
35+
)
36+
]
37+
)

core/swift54Action/_Whisk.swift

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import Foundation
19+
import Dispatch
20+
#if canImport(FoundationNetworking)
21+
import FoundationNetworking
22+
#endif
23+
24+
class Whisk {
25+
26+
static var baseUrl = ProcessInfo.processInfo.environment["__OW_API_HOST"]
27+
static var apiKey = ProcessInfo.processInfo.environment["__OW_API_KEY"]
28+
// This will allow user to modify the default JSONDecoder and JSONEncoder used by epilogue
29+
static var jsonDecoder = JSONDecoder()
30+
static var jsonEncoder = JSONEncoder()
31+
32+
class func invoke(actionNamed action : String, withParameters params : [String:Any], blocking: Bool = true) -> [String:Any] {
33+
let parsedAction = parseQualifiedName(name: action)
34+
let strBlocking = blocking ? "true" : "false"
35+
let path = "/api/v1/namespaces/\(parsedAction.namespace)/actions/\(parsedAction.name)?blocking=\(strBlocking)"
36+
37+
return sendWhiskRequestSyncronish(uriPath: path, params: params, method: "POST")
38+
}
39+
40+
class func trigger(eventNamed event : String, withParameters params : [String:Any]) -> [String:Any] {
41+
let parsedEvent = parseQualifiedName(name: event)
42+
let path = "/api/v1/namespaces/\(parsedEvent.namespace)/triggers/\(parsedEvent.name)?blocking=true"
43+
44+
return sendWhiskRequestSyncronish(uriPath: path, params: params, method: "POST")
45+
}
46+
47+
class func createTrigger(triggerNamed trigger: String, withParameters params : [String:Any]) -> [String:Any] {
48+
let parsedTrigger = parseQualifiedName(name: trigger)
49+
let path = "/api/v1/namespaces/\(parsedTrigger.namespace)/triggers/\(parsedTrigger.name)"
50+
return sendWhiskRequestSyncronish(uriPath: path, params: params, method: "PUT")
51+
}
52+
53+
class func createRule(ruleNamed ruleName: String, withTrigger triggerName: String, andAction actionName: String) -> [String:Any] {
54+
let parsedRule = parseQualifiedName(name: ruleName)
55+
let path = "/api/v1/namespaces/\(parsedRule.namespace)/rules/\(parsedRule.name)"
56+
let params = ["trigger":triggerName, "action":actionName]
57+
return sendWhiskRequestSyncronish(uriPath: path, params: params, method: "PUT")
58+
}
59+
60+
// handle the GCD dance to make the post async, but then obtain/return
61+
// the result from this function sync
62+
private class func sendWhiskRequestSyncronish(uriPath path: String, params : [String:Any], method: String) -> [String:Any] {
63+
var response : [String:Any]!
64+
65+
let queue = DispatchQueue.global()
66+
let invokeGroup = DispatchGroup()
67+
68+
invokeGroup.enter()
69+
queue.async {
70+
postUrlSession(uriPath: path, params: params, method: method, group: invokeGroup) { result in
71+
response = result
72+
}
73+
}
74+
75+
// On one hand, FOREVER seems like an awfully long time...
76+
// But on the other hand, I think we can rely on the system to kill this
77+
// if it exceeds a reasonable execution time.
78+
switch invokeGroup.wait(timeout: DispatchTime.distantFuture) {
79+
case DispatchTimeoutResult.success:
80+
break
81+
case DispatchTimeoutResult.timedOut:
82+
break
83+
}
84+
85+
return response
86+
}
87+
88+
89+
/**
90+
* Using new UrlSession
91+
*/
92+
private class func postUrlSession(uriPath: String, params : [String:Any], method: String,group: DispatchGroup, callback : @escaping([String:Any]) -> Void) {
93+
94+
guard let encodedPath = uriPath.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) else {
95+
callback(["error": "Error encoding uri path to make openwhisk REST call."])
96+
return
97+
}
98+
99+
let urlStr = "\(baseUrl!)\(encodedPath)"
100+
if let url = URL(string: urlStr) {
101+
var request = URLRequest(url: url)
102+
request.httpMethod = method
103+
104+
do {
105+
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
106+
request.httpBody = try JSONSerialization.data(withJSONObject: params)
107+
108+
let loginData: Data = apiKey!.data(using: String.Encoding.utf8, allowLossyConversion: false)!
109+
let base64EncodedAuthKey = loginData.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
110+
request.addValue("Basic \(base64EncodedAuthKey)", forHTTPHeaderField: "Authorization")
111+
let session = URLSession(configuration: URLSessionConfiguration.default)
112+
113+
let task = session.dataTask(with: request, completionHandler: {data, response, error -> Void in
114+
115+
// exit group after we are done
116+
defer {
117+
group.leave()
118+
}
119+
120+
if let error = error {
121+
callback(["error":error.localizedDescription])
122+
} else {
123+
124+
if let data = data {
125+
do {
126+
//let outputStr = String(data: data, encoding: String.Encoding.utf8) as String!
127+
//print(outputStr)
128+
let respJson = try JSONSerialization.jsonObject(with: data)
129+
if respJson is [String:Any] {
130+
callback(respJson as! [String:Any])
131+
} else {
132+
callback(["error":" response from server is not a dictionary"])
133+
}
134+
} catch {
135+
callback(["error":"Error creating json from response: \(error)"])
136+
}
137+
}
138+
}
139+
})
140+
141+
task.resume()
142+
} catch {
143+
callback(["error":"Got error creating params body: \(error)"])
144+
}
145+
}
146+
}
147+
148+
// separate an OpenWhisk qualified name (e.g. "/whisk.system/samples/date")
149+
// into namespace and name components
150+
private class func parseQualifiedName(name qualifiedName : String) -> (namespace : String, name : String) {
151+
let defaultNamespace = "_"
152+
let delimiter = "/"
153+
154+
let segments :[String] = qualifiedName.components(separatedBy: delimiter)
155+
156+
if segments.count > 2 {
157+
return (segments[1], Array(segments[2..<segments.count]).joined(separator: delimiter))
158+
} else if segments.count == 2 {
159+
// case "/action" or "package/action"
160+
let name = qualifiedName.hasPrefix(delimiter) ? segments[1] : segments.joined(separator: delimiter)
161+
return (defaultNamespace, name)
162+
} else {
163+
return (defaultNamespace, segments[0])
164+
}
165+
}
166+
167+
}

core/swift54Action/build.gradle

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
ext.dockerImageName = 'action-swift-v5.4'
19+
apply from: '../../gradle/docker.gradle'

core/swift54Action/main.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
func main(args: [String:Any]) -> [String:Any] {
19+
if let name = args["name"] as? String {
20+
return [ "greeting" : "Hello \(name)!" ]
21+
} else {
22+
return [ "greeting" : "Hello stranger!" ]
23+
}
24+
}

0 commit comments

Comments
 (0)