From eb025c95ed011dd2af69865e9887d40c9461e7fb Mon Sep 17 00:00:00 2001 From: Shawn Feldman Date: Thu, 22 Jan 2015 12:27:26 -0700 Subject: [PATCH] moving files to own dir refactor for compile issues adding badges refactor interfaces ignore nuget packages documentation remove excess methods add multiple notifications sanitizing code change text update uri change data type refactor properties in winphone client changing names of variables --- .gitignore | 1 + portal/js/push/push-config.html | 6 +- .../notifications/Usergrid.Notifications.sln | 40 ++++ .../Usergrid.Notifications/App.xaml | 22 +- .../Usergrid.Notifications/App.xaml.cs | 21 +- .../Client/EntityResponse.cs | 80 +++++++ .../Client/IUsergridClient.cs | 123 +++++++++++ .../Client/PushClient.cs | 153 +++++++++++++ .../Usergrid.Notifications/Client/Usergrid.cs | 120 ++++++++++ .../Usergrid.Notifications/MainPage.xaml | 32 ++- .../Usergrid.Notifications/MainPage.xaml.cs | 98 +++++--- .../Package.appxmanifest | 23 +- .../Usergrid.Notifications.csproj | 5 +- .../Usergrid.Notifications/Usergrid.cs | 209 ------------------ .../Usergrid.Notifications/packages.config | 21 ++ .../packages/repositories.config | 4 + .../impl/ApplicationQueueManagerImpl.java | 8 +- .../wns/TranslatedNotification.java | 50 +++++ .../notifications/wns/WNSAdapter.java | 55 ++++- 19 files changed, 805 insertions(+), 266 deletions(-) create mode 100644 sdks/dotnet/samples/notifications/Usergrid.Notifications.sln create mode 100644 sdks/dotnet/samples/notifications/Usergrid.Notifications/Client/EntityResponse.cs create mode 100644 sdks/dotnet/samples/notifications/Usergrid.Notifications/Client/IUsergridClient.cs create mode 100644 sdks/dotnet/samples/notifications/Usergrid.Notifications/Client/PushClient.cs create mode 100644 sdks/dotnet/samples/notifications/Usergrid.Notifications/Client/Usergrid.cs delete mode 100644 sdks/dotnet/samples/notifications/Usergrid.Notifications/Usergrid.cs create mode 100644 sdks/dotnet/samples/notifications/packages/repositories.config create mode 100644 stack/services/src/main/java/org/apache/usergrid/services/notifications/wns/TranslatedNotification.java diff --git a/.gitignore b/.gitignore index 05c865c6c5..522f674c9f 100644 --- a/.gitignore +++ b/.gitignore @@ -84,3 +84,4 @@ portal/js/templates.js /stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/QueryFilterParser.java !/stack/corepersistence/common/src/test/resources/usergrid-UNIT.properties *.iml +sdks/dotnet/samples/notifications/packages/* diff --git a/portal/js/push/push-config.html b/portal/js/push/push-config.html index 8dbdf38811..8cacab0d05 100644 --- a/portal/js/push/push-config.html +++ b/portal/js/push/push-config.html @@ -165,7 +165,7 @@
A Notifier allows App Services to connect to and deliver a message to a communication provider such as Windows Notifications Service (WNS). Copy and paste your API key to create a bridge between your app - and GCM for push notifications on Android devices.. + and WNS for push notifications on windows devices..

For more help: see our getting started page page. @@ -189,10 +189,12 @@
- API Key + Secret
+
+ Secret will not be returned in other api calls for security reasons.
diff --git a/sdks/dotnet/samples/notifications/Usergrid.Notifications.sln b/sdks/dotnet/samples/notifications/Usergrid.Notifications.sln new file mode 100644 index 0000000000..5474b5b7f1 --- /dev/null +++ b/sdks/dotnet/samples/notifications/Usergrid.Notifications.sln @@ -0,0 +1,40 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Usergrid.Notifications", "Usergrid.Notifications\Usergrid.Notifications.csproj", "{EB364B8E-B7C1-45C2-BF13-1CBF731EA8B6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|ARM = Debug|ARM + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|ARM = Release|ARM + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EB364B8E-B7C1-45C2-BF13-1CBF731EA8B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EB364B8E-B7C1-45C2-BF13-1CBF731EA8B6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EB364B8E-B7C1-45C2-BF13-1CBF731EA8B6}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {EB364B8E-B7C1-45C2-BF13-1CBF731EA8B6}.Debug|ARM.ActiveCfg = Debug|ARM + {EB364B8E-B7C1-45C2-BF13-1CBF731EA8B6}.Debug|ARM.Build.0 = Debug|ARM + {EB364B8E-B7C1-45C2-BF13-1CBF731EA8B6}.Debug|ARM.Deploy.0 = Debug|ARM + {EB364B8E-B7C1-45C2-BF13-1CBF731EA8B6}.Debug|x86.ActiveCfg = Debug|x86 + {EB364B8E-B7C1-45C2-BF13-1CBF731EA8B6}.Debug|x86.Build.0 = Debug|x86 + {EB364B8E-B7C1-45C2-BF13-1CBF731EA8B6}.Debug|x86.Deploy.0 = Debug|x86 + {EB364B8E-B7C1-45C2-BF13-1CBF731EA8B6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EB364B8E-B7C1-45C2-BF13-1CBF731EA8B6}.Release|Any CPU.Build.0 = Release|Any CPU + {EB364B8E-B7C1-45C2-BF13-1CBF731EA8B6}.Release|Any CPU.Deploy.0 = Release|Any CPU + {EB364B8E-B7C1-45C2-BF13-1CBF731EA8B6}.Release|ARM.ActiveCfg = Release|ARM + {EB364B8E-B7C1-45C2-BF13-1CBF731EA8B6}.Release|ARM.Build.0 = Release|ARM + {EB364B8E-B7C1-45C2-BF13-1CBF731EA8B6}.Release|ARM.Deploy.0 = Release|ARM + {EB364B8E-B7C1-45C2-BF13-1CBF731EA8B6}.Release|x86.ActiveCfg = Release|x86 + {EB364B8E-B7C1-45C2-BF13-1CBF731EA8B6}.Release|x86.Build.0 = Release|x86 + {EB364B8E-B7C1-45C2-BF13-1CBF731EA8B6}.Release|x86.Deploy.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/sdks/dotnet/samples/notifications/Usergrid.Notifications/App.xaml b/sdks/dotnet/samples/notifications/Usergrid.Notifications/App.xaml index 8a363591d4..486a2fdf55 100644 --- a/sdks/dotnet/samples/notifications/Usergrid.Notifications/App.xaml +++ b/sdks/dotnet/samples/notifications/Usergrid.Notifications/App.xaml @@ -3,5 +3,25 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Usergrid.Notifications"> - + \ No newline at end of file diff --git a/sdks/dotnet/samples/notifications/Usergrid.Notifications/App.xaml.cs b/sdks/dotnet/samples/notifications/Usergrid.Notifications/App.xaml.cs index 9bf62ac99b..eb079fbba1 100644 --- a/sdks/dotnet/samples/notifications/Usergrid.Notifications/App.xaml.cs +++ b/sdks/dotnet/samples/notifications/Usergrid.Notifications/App.xaml.cs @@ -1,4 +1,23 @@ -using System; +/* + * + * * Licensed to the Apache Software Foundation (ASF) under one or more + * * contributor license agreements. The ASF licenses this file to You + * * under the Apache License, Version 2.0 (the "License"); you may not + * * use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. For additional information regarding + * * copyright in this work, please see the NOTICE file in the top level + * * directory of this distribution. + * + */ +using System; using System.Collections.Generic; using System.IO; using System.Linq; diff --git a/sdks/dotnet/samples/notifications/Usergrid.Notifications/Client/EntityResponse.cs b/sdks/dotnet/samples/notifications/Usergrid.Notifications/Client/EntityResponse.cs new file mode 100644 index 0000000000..0be267a061 --- /dev/null +++ b/sdks/dotnet/samples/notifications/Usergrid.Notifications/Client/EntityResponse.cs @@ -0,0 +1,80 @@ +/* + * + * * Licensed to the Apache Software Foundation (ASF) under one or more + * * contributor license agreements. The ASF licenses this file to You + * * under the Apache License, Version 2.0 (the "License"); you may not + * * use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. For additional information regarding + * * copyright in this work, please see the NOTICE file in the top level + * * directory of this distribution. + * + */ + +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; + +namespace Usergrid.Notifications.Client +{ + public class EntityResponse : JObject + { + private HttpResponseMessage response; + + private EntityResponse(HttpResponseMessage response, JObject jObject) + : base() + { + this.response = response; + parseResponse(jObject); + } + + private void parseResponse(JObject jobject) + { + foreach (var kv in jobject) + { + this[kv.Key] = kv.Value; + } + } + + public HttpStatusCode Status + { + get { return this.response.StatusCode; } + } + + public static async Task Parse(HttpResponseMessage httpResponseMessage) + { + JObject jobject; + + using (var stream = await httpResponseMessage.Content.ReadAsStreamAsync()) + { + using (var reader = new StreamReader(stream, Encoding.UTF8)) + { + jobject = JObject.Parse(reader.ReadToEnd()); + } + } + + return new EntityResponse(httpResponseMessage, jobject); + } + + public bool StatusIsOk + { + get + { + return this.Status == HttpStatusCode.OK; + } + } + } +} diff --git a/sdks/dotnet/samples/notifications/Usergrid.Notifications/Client/IUsergridClient.cs b/sdks/dotnet/samples/notifications/Usergrid.Notifications/Client/IUsergridClient.cs new file mode 100644 index 0000000000..3f4fb82242 --- /dev/null +++ b/sdks/dotnet/samples/notifications/Usergrid.Notifications/Client/IUsergridClient.cs @@ -0,0 +1,123 @@ +/* + * + * * Licensed to the Apache Software Foundation (ASF) under one or more + * * contributor license agreements. The ASF licenses this file to You + * * under the Apache License, Version 2.0 (the "License"); you may not + * * use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. For additional information regarding + * * copyright in this work, please see the NOTICE file in the top level + * * directory of this distribution. + * + */ + +using Newtonsoft.Json.Linq; +using System; +using System.Net.Http; +using System.Threading.Tasks; +using Windows.Networking.PushNotifications; +namespace Usergrid.Notifications.Client +{ + /// + /// encapsulates usergrid calls, use UsergridFactory + /// + public interface IUsergridClient + { + /// + /// Authenticate your calls + /// + /// + /// + /// + /// + Task Authenticate(string user, string password, bool isManagement); + /// + /// Send a message + /// + /// + /// + /// + /// + Task SendAsync(HttpMethod method, string url, object obj); + /// + /// Send a message + /// + /// + /// + /// + /// + /// + Task SendAsync(HttpMethod method, string url, object obj, bool useManagementUrl); + /// + /// Reference the push client, you should call register before using + /// + IPushClient Push { get; } + + Exception LastException { get; } + + } + + /// + /// Only show http calls + /// + public interface IUsergridHttpClient + { + /// + /// Send Http call async + /// + /// + /// + /// + /// use management endpoint + /// + Task SendAsync(HttpMethod method, string url, object obj, bool useManagementUrl); + /// + /// send Http call async + /// + /// + /// + /// + /// + Task SendAsync(HttpMethod method, string url, object obj); + } + + /// + /// Push client, call register + /// + public interface IPushClient + { + /// + /// the notifier you are currently using + /// + string Notifier { get; set; } + + /// + /// Device id in usergrid + /// + Guid DeviceId { get; set; } + /// + /// send a toast + /// + /// + /// + Task SendToast(string message); + + /// + /// Send a badge update + /// + /// + /// + Task SendBadge(T message); + + Exception LastException { get; } + + } + +} diff --git a/sdks/dotnet/samples/notifications/Usergrid.Notifications/Client/PushClient.cs b/sdks/dotnet/samples/notifications/Usergrid.Notifications/Client/PushClient.cs new file mode 100644 index 0000000000..8668626fec --- /dev/null +++ b/sdks/dotnet/samples/notifications/Usergrid.Notifications/Client/PushClient.cs @@ -0,0 +1,153 @@ +/* + * + * * Licensed to the Apache Software Foundation (ASF) under one or more + * * contributor license agreements. The ASF licenses this file to You + * * under the Apache License, Version 2.0 (the "License"); you may not + * * use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. For additional information regarding + * * copyright in this work, please see the NOTICE file in the top level + * * directory of this distribution. + * + */ +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Windows.Networking.PushNotifications; +using Windows.Storage; + +namespace Usergrid.Notifications.Client +{ + public class PushClient : IPushClient + { + const string DEVICE_KEY = "currentDeviceId"; + private IUsergridHttpClient usergrid; + private ApplicationDataContainer settings; + private PushNotificationChannel channel; + + public PushClient(IUsergridHttpClient usergrid, string notifier) + { + this.usergrid = usergrid; + this.settings = ApplicationData.Current.LocalSettings; + this.Notifier = notifier; + this.init().ContinueWith(t => + { + LastException = t.Exception; + } + ); + } + + + public async Task SendToast(string message) + { + if (DeviceId == null) + { + throw new Exception("Please call PushClient.RegisterDevice first."); + } + var jsonObject = new JObject(); + var payloads = new JObject(); + var payload = new JObject(); + payload.Add("toast", new JValue(message)); + payloads.Add(Notifier, payload); + jsonObject.Add("payloads", payloads); + jsonObject.Add("debug", true); + var jsonResponse = await usergrid.SendAsync(HttpMethod.Post, String.Format("devices/{0}/notifications", this.DeviceId), jsonObject); + return jsonResponse.StatusIsOk; + } + + public async Task SendBadge(T message) + { + if (DeviceId == null) + { + throw new Exception("Please call PushClient.RegisterDevice first."); + } + var jsonObject = new JObject(); + var payloads = new JObject(); + var payload = new JObject(); + payload.Add("badge", new JValue(message)); + payloads.Add(Notifier, payload); + jsonObject.Add("payloads", payloads); + jsonObject.Add("debug", true); + var jsonResponse = await usergrid.SendAsync(HttpMethod.Post, String.Format("devices/{0}/notifications", this.DeviceId), jsonObject); + return jsonResponse.StatusIsOk; + } + + private async Task init() + { + channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync().AsTask(); + if (settings.Values[DEVICE_KEY] == null) + { + Guid uuid = await registerDevice(true); + settings.Values.Add(DEVICE_KEY, uuid); + this.DeviceId = uuid; + } + else + { + object tempId; + settings.Values.TryGetValue(DEVICE_KEY, out tempId); + this.DeviceId = Guid.Parse(tempId.ToString()); + var device = await GetDevice(DeviceId); + if (device == null) + { + Guid uuid = await registerDevice(true); + settings.Values[DEVICE_KEY] = uuid; + this.DeviceId = uuid; + } + else + { + await registerDevice(false); + } + } + } + + + private async Task GetDevice(Guid deviceId) + { + var jsonResponse = await usergrid.SendAsync(HttpMethod.Get, "devices/" + deviceId, null); + + if (jsonResponse.StatusIsOk) + { + var body = jsonResponse.GetValue("entities"); + return body != null && body.Value().Count > 0 ? body.Value()[0] : null; + } + else { return null; } + } + + private async Task registerDevice(bool isNew) + { + JObject obj = new JObject(); + obj.Add(Notifier + ".notifier.id", new JValue(channel.Uri)); + var jsonResponse = await usergrid.SendAsync( + (isNew ? HttpMethod.Post : HttpMethod.Put), + "devices/" + (isNew ? "" : this.DeviceId.ToString()), + obj + ); + + if (jsonResponse.StatusIsOk) + { + var entity = jsonResponse.GetValue("entities").Value()[0]; + var uuid = Guid.Parse(entity.Value("uuid")); + return uuid; + } + else { + return Guid.Empty; + } + } + + public string Notifier { get; set; } + public Guid DeviceId { get; set; } + public Exception LastException { get; set; } + + } +} diff --git a/sdks/dotnet/samples/notifications/Usergrid.Notifications/Client/Usergrid.cs b/sdks/dotnet/samples/notifications/Usergrid.Notifications/Client/Usergrid.cs new file mode 100644 index 0000000000..cd0330df3b --- /dev/null +++ b/sdks/dotnet/samples/notifications/Usergrid.Notifications/Client/Usergrid.cs @@ -0,0 +1,120 @@ +/* + * + * * Licensed to the Apache Software Foundation (ASF) under one or more + * * contributor license agreements. The ASF licenses this file to You + * * under the Apache License, Version 2.0 (the "License"); you may not + * * use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. For additional information regarding + * * copyright in this work, please see the NOTICE file in the top level + * * directory of this distribution. + * + */ + +using System; +using System.Threading.Tasks; +using System.Net; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json; +using System.Net.Http; +using System.Net.Http.Headers; + +namespace Usergrid.Notifications.Client +{ + + /// + /// Usergrid client + /// + + public class Usergrid : IUsergridHttpClient, IUsergridClient + { + private string appUrl; + private string token; + private HttpClient client; + private IPushClient push; + private string managementUrl; + + /// + /// Constructor + /// + /// + /// + /// + /// + internal Usergrid(string serverUrl, string org, string app, string notifier) + { + string serverUrlWithSlash = serverUrl.EndsWith("/", StringComparison.CurrentCulture) ? serverUrl : serverUrl + "/"; + this.appUrl = String.Format("{0}{1}/{2}/", serverUrlWithSlash, org, app); + this.managementUrl = serverUrlWithSlash + "management/"; + this.client = new HttpClient(); + this.push = new PushClient(this,notifier); + } + + public async Task Authenticate(string user, string password, bool isManagement) + { + var jsonObject = new JObject(); + jsonObject.Add("username", user); + jsonObject.Add("password", password); + jsonObject.Add("grant_type", "password"); + + var response = await SendAsync(HttpMethod.Post,"token", jsonObject, isManagement); + + if (response.StatusIsOk) + { + this.token = response.GetValue("access_token").Value(); + client.DefaultRequestHeaders.Add("X-Authorization", token); + } + else + { + throw new Exception("Authentication failed: "+response.ToString()); + } + } + + private async Task GetJsonResponse(HttpResponseMessage response) + { + return await EntityResponse.Parse(response); + } + + public async Task SendAsync(HttpMethod method, string url, object obj) + { + return await SendAsync(method, url, obj, false); + } + + public async Task SendAsync(HttpMethod method, string url, object obj, bool useManagementUrl) + { + HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Post, (useManagementUrl ? this.managementUrl : this.appUrl) + url); + if (obj != null) + { + message.Content = getJsonBody(obj); + } + message.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue( "application/json")); + var response = await this.client.SendAsync(message); + return await EntityResponse.Parse(response); + } + + public IPushClient Push + { + get { return push; } + } + + private HttpContent getJsonBody(Object jsonObject) + { + return new StringContent(JsonConvert.SerializeObject(jsonObject)); + } + + + public Exception LastException + { + get; + set; + } + } + +} diff --git a/sdks/dotnet/samples/notifications/Usergrid.Notifications/MainPage.xaml b/sdks/dotnet/samples/notifications/Usergrid.Notifications/MainPage.xaml index 3e0affdb58..f22c8b6616 100644 --- a/sdks/dotnet/samples/notifications/Usergrid.Notifications/MainPage.xaml +++ b/sdks/dotnet/samples/notifications/Usergrid.Notifications/MainPage.xaml @@ -7,14 +7,32 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> - + - -