<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Falafel Software Blog</title>
	<atom:link href="https://blog.falafel.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.falafel.com</link>
	<description>Excellence in Software Services</description>
	<lastBuildDate>Wed, 22 Mar 2017 14:00:03 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.8.1</generator>

<image>
	<url>https://blog.falafel.com/wp-content/uploads/2015/09/cropped-falafel.com_-32x32.png</url>
	<title>Falafel Software Blog</title>
	<link>https://blog.falafel.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">72017644</site>	<item>
		<title>Matching Complex Query String Rewrite Rule in IIS</title>
		<link>https://blog.falafel.com/matching-query-string-rewrite-rule-iis/</link>
		<comments>https://blog.falafel.com/matching-query-string-rewrite-rule-iis/#comments</comments>
		<pubDate>Wed, 22 Mar 2017 14:00:03 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[IIS]]></category>
		<category><![CDATA[Administration]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[URL Rewrite]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6227</guid>
		<description><![CDATA[<p>IIS URL Rewrite Doesn&#8217;t Find My Query String Rule. Help! I recently had to handle a particular request from a client: They had sent out a newsletter that linked to their site, but had sent the wrong URL. As such, they needed the site to redirect the bad URL to the correct one. The bad URL linked to a page that passed along query string parameters. A simple request and a simple fix, right? Well, as I delved into the site&#8217;s rewrite rules, I quickly found out that the URL I needed to match was not matching. Worse still, it...</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/matching-query-string-rewrite-rule-iis/">Matching Complex Query String Rewrite Rule in IIS</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<h2>IIS URL Rewrite Doesn&#8217;t Find My Query String Rule. Help!</h2>
<p>I recently had to handle a particular request from a client: They had sent out a newsletter that linked to their site, but had sent the wrong URL. As such, they needed the site to redirect the bad URL to the correct one. The bad URL linked to a page that passed along query string parameters. A simple request and a simple fix, right? Well, as I delved into the site&#8217;s rewrite rules, I quickly found out that the URL I needed to match was not matching. Worse still, it was making the site break! As it turns out, writing a query string rewrite rule takes a little more effort than simply doing an exact match on the URL itself.</p>
<h2>First Attempt</h2>
<p>Here&#8217;s the rule I started out with. I cracked open my <a href="https://blog.falafel.com/configsource-rewrite-rules/">separated rewrite rules config file</a> and got to writing. Here&#8217;s what I ended up with at first (with details changed to protect the innocent):</p>
<pre class="crayon-plain-tag">&lt;rule name="Redirect Incorrect URL" stopProcessing="true"&gt;
  &lt;match url="^wrong-page?foo=11&amp;bar=20$" /&gt;
  &lt;action type="Redirect" url="correct-page" appendQueryString="false" /&gt;
&lt;/rule&gt;</pre>
<p>If I didn&#8217;t have a complex query string (i.e. one with multiple parameters), or any query string at all for that matter, I&#8217;d be done. Instead my local development copy of the site went down! It was throwing an HTTP 500 error and nothing more. (Incidentally, this is why you never make changes, even simple ones, on production!) What gives?</p>
<h2>Encoding the Ampersands and Splitting the Query String</h2>
<p>In our query string rewrite rule, the first change is to encode the ampersands. Our web application in IIS was tripping up on those characters. We also need to move the query string. IIS reads the URL well enough in the &lt;match&gt; element, but the query string is a separate piece altogether, and needs to be moved to the &lt;conditions&gt; element instead.</p>
<pre class="crayon-plain-tag">&lt;rule name="Redirect Incorrect URL" stopProcessing="true"&gt;
  &lt;match url="^wrong-page$" /&gt;
  &lt;action type="Redirect" url="correct-page" appendQueryString="false" /&gt;
  &lt;conditions&gt;
    &lt;add input="{QUERY_STRING}" pattern="^foo=11&amp;amp;bar=20$" /&gt;
  &lt;/conditions&gt;
&lt;/rule&gt;</pre>
<p>We&#8217;re good now right? Wrong! While the site was no longer crashing down on me, the rewrite rule was not matching despite entering that exact URL. There was one smaller change I needed to make in order to get this query string rewrite rule matching.</p>
<h2>Eliminating the Money and Making it Work</h2>
<p>Our query string rewrite rule didn&#8217;t match because we specified the end-of-string regular expression symbol in our &lt;match&gt; element. IIS seems to ignore anything past that symbol, including items in the condition, despite my initial thinking. Once I got rid of the $ symbol, it all fell into place and began working. Here is the final, working query string rewrite rule:</p>
<pre class="crayon-plain-tag">&lt;rule name="Redirect Incorrect URL" stopProcessing="true"&gt;
  &lt;match url="^wrong-page" /&gt;
  &lt;action type="Redirect" url="correct-page" appendQueryString="false" /&gt;
  &lt;conditions&gt;
    &lt;add input="{QUERY_STRING}" pattern="^foo=11&amp;amp;bar=20$" /&gt;
  &lt;/conditions&gt;
&lt;/rule&gt;</pre>
<h2>Summary</h2>
<p>In this case, a simple request led me on a little journey through the various workings of IIS rewrite. Despite working with it for some time now, I still managed to come across something new!</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/matching-query-string-rewrite-rule-iis/">Matching Complex Query String Rewrite Rule in IIS</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/matching-query-string-rewrite-rule-iis/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6227</post-id>	</item>
		<item>
		<title>Disable Content Filters in Sitefinity</title>
		<link>https://blog.falafel.com/disable-sitefinity-content-filters/</link>
		<comments>https://blog.falafel.com/disable-sitefinity-content-filters/#respond</comments>
		<pubDate>Wed, 08 Mar 2017 15:00:05 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[Sitefinity]]></category>
		<category><![CDATA[Administration]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[Sitefinity 8]]></category>
		<category><![CDATA[Sitefinity 9]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6221</guid>
		<description><![CDATA[<p>My HTML is Changing! Sitefinity gives you a lot of power. One of the many tools at your disposal is the ability to enter HTML in Content Blocks (either inline on a page, or in the Content Block type that can be shared among multiple pages). A common gotcha with new applications, however, is how Sitefinity filters these. Content filters exist out of the box in Sitefinity to presumably do two things: Standardize content entry (i.e. transform all &#60;i&#62; tags to &#60;em&#62; tags) Security precaution (i.e. strip out &#60;script&#62; tags) While both of these traits are admirable on paper, a...</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/disable-sitefinity-content-filters/">Disable Content Filters in Sitefinity</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<h2>My HTML is Changing!</h2>
<p>Sitefinity gives you a lot of power. One of the many tools at your disposal is the ability to enter HTML in Content Blocks (either inline on a page, or in the Content Block type that can be shared among multiple pages). A common gotcha with new applications, however, is how Sitefinity filters these. Content filters exist out of the box in Sitefinity to presumably do two things:</p>
<ul>
<li>Standardize content entry (i.e. transform all &lt;i&gt; tags to &lt;em&gt; tags)</li>
<li>Security precaution (i.e. strip out &lt;script&gt; tags)</li>
</ul>
<p>While both of these traits are admirable on paper, a lot of the time they can get in the way. In our normal Sitefinity development and design workflows, we already trust every user with backend access to not enter malicious scripting, etc. Therefore when we set up a new Sitefinity application, one of the first things we do is disable these content filters so that we can work unhindered.</p>
<h2>The Problem</h2>
<p>Here&#8217;s an example of a Content Block&#8217;s HTML content getting changed on the fly in Sitefinity, due to the existing content filters. This scenario occurs both when attempting to edit content blocks on pages and when attempting to edit Content Blocks in Content &gt; Content blocks.</p>
<p><img src="https://blog.falafel.com/wp-content/uploads/2017/03/01-content-block-on-page.gif" alt="Editing Content with Content Filters Enabled" /></p>
<h2>The Fix</h2>
<p>These content filters can be frustrating if you don&#8217;t catch them or don&#8217;t know why they&#8217;re happening! Luckily they&#8217;re easy enough to disable.</p>
<ul>
<li>Hop on over to Administration &gt; Settings, click Advanced, then Appearance. Within your site, you can go directly to this screen by visiting http://www.example.com/Sitefinity/Administration/Settings/Advanced/Appearance.</li>
<li>Here you will find three settings: <strong>RadEditor filters for Content block widget</strong>, <strong>Rad Editor&#8217;s content filters</strong>, and <strong>Rad Editor strip formatting options</strong>.</li>
<li>Change all of these settings to &#8220;None&#8221; (without the quotes).</li>
<li>Click &#8220;Save changes.&#8221;</li>
</ul>
<p><img src="https://blog.falafel.com/wp-content/uploads/2017/03/02-disable-content-filters.png" alt="Settings to Disable Content Filters" /></p>
<h2>Content Entry Unfiltered</h2>
<p>Now that we&#8217;ve disabled the content filters, we can freely enter content in the Sitefinity backend without worrying about Sitefinity changing or deleting our work. As before, this applies both to content blocks on pages and to content blocks created as content items in Sitefinity proper.</p>
<p><img src="https://blog.falafel.com/wp-content/uploads/2017/03/03-content-block-no-filtering.gif" alt="Content Filters No Longer Apply" /></p>
<h2>Content Filters and Sitefinity Feather</h2>
<p>The above content filter disabling practice only applies to the classic set of widgets and content. They do <em>not</em> apply to Sitefinity MVC Feather widgets. Feather content blocks have a separate means of filtering and formatting, which I addressed in a <a href="https://blog.falafel.com/preserve-feather-content-block-formatting/">previous post of mine</a>. But the content filters discussed here have no bearing on those.</p>
<h2>Summary</h2>
<p>Sitefinity has content filters in place to help preserve consistency and to help with security. In a lot of scenarios, these are redundant and can get in the way of content entry, design, or development. Sitefinity exposes these settings to allow for easy disabling of the content filters to allow you to go unhindered when entering content going forward.</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/disable-sitefinity-content-filters/">Disable Content Filters in Sitefinity</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/disable-sitefinity-content-filters/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6221</post-id>	</item>
		<item>
		<title>Falafel Software Recognized for Sitefinity Website of the Year</title>
		<link>https://blog.falafel.com/falafel-software-recognized-sitefinity-website-year/</link>
		<comments>https://blog.falafel.com/falafel-software-recognized-sitefinity-website-year/#respond</comments>
		<pubDate>Thu, 02 Mar 2017 19:40:24 +0000</pubDate>
		<dc:creator><![CDATA[Lino Tadros]]></dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Sitefinity]]></category>
		<category><![CDATA[Award]]></category>
		<category><![CDATA[Progress]]></category>
		<category><![CDATA[Telerik]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6243</guid>
		<description><![CDATA[<p>Falafel Software Announces that Mammoth Mountain Resorts Wins Progress Sitefinity 2016 Website of the Year Award Company’s work with Big Bear Mountain Resort honored for the best in website creativity, design, user experience, functionality and overall presentation  Scotts Valley, CA—February 28, 2017—Falafel Software today announced that the Big Bear Mountain Resort website, designed and built by Falafel Software has been named a 2016 Progress® Sitefinity™ Website of the Year winner in the Tourism &#38; Hospitality category. Since its inception in 2011, the Website of the Year awards have been recognizing Progress Sitefinity-powered websites for creativity, design, user experience, functionality and overall...</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/falafel-software-recognized-sitefinity-website-year/">Falafel Software Recognized for Sitefinity Website of the Year</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<h2>Falafel Software Announces that Mammoth Mountain Resorts Wins Progress Sitefinity 2016 Website of the Year Award</h2>
<p><em>Company’s work with Big Bear Mountain Resort honored </em><em>for the best in website creativity, design, user experience, functionality and overall presentation</em></p>
<p><em> </em><strong>Scotts Valley, CA—February 28, 2017—</strong>Falafel Software today announced that the Big Bear Mountain Resort website, designed and built by Falafel Software has been named a 2016 Progress<sup>®</sup> Sitefinity™ Website of the Year winner in the Tourism &amp; Hospitality category. Since its inception in 2011, the Website of the Year awards have been recognizing Progress Sitefinity-powered websites for creativity, design, user experience, functionality and overall website presentation.</p>
<p><em>“On behalf of Progress, I would like to congratulate Falafel Software on this terrific achievement,” said Kimberly King, Vice President, Global Partners and Channels, Progress. “While the Sitefinity platform is trusted and used by thousands of customers worldwide to create and optimize customer experiences across channels, these awards honor the progressive companies that are truly setting the pace for others.”</em></p>
<p>“<em>Congratulations to the entire Mammoth Mountain team for the award and the great achievement,” said Lino Tadros, President &amp; CEO, Falafel Software. “Our team at Falafel enjoyed working on the site and with your talented team.  Thank you also to Progress for recognizing our quality of work and the greatness of the Big Bear Mountain Resort web site”.</em></p>
<p>More information about the contest and the winners is available on the <a href="http://www.sitefinity.com/customers/website-of-the-year/2015">“Website of the Year” page</a>.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/03/SitefinityWinner2017.png" rel="prettyPhoto[gallery-lw11]"><img class="size-medium wp-image-6245 alignnone" src="https://blog.falafel.com/wp-content/uploads/2017/03/SitefinityWinner2017-300x212.png" alt="CertificateSitefinity2016" width="300" height="212" srcset="https://blog.falafel.com/wp-content/uploads/2017/03/SitefinityWinner2017-300x212.png 300w, https://blog.falafel.com/wp-content/uploads/2017/03/SitefinityWinner2017-768x542.png 768w, https://blog.falafel.com/wp-content/uploads/2017/03/SitefinityWinner2017-1024x723.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/03/SitefinityWinner2017.png 1460w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p><strong>About Falafel Software</strong></p>
<p><a href="http://falafel.com">Falafel</a> Software Inc., a Microsoft Silver Certified partner and a Telerik Platinum Partner for 14 years, has been providing custom software development, consultation, and training services worldwide since 2003. We are a 100% US-based team of Sr. Software Engineers, Marketers and UI/UX designers. Our team of Microsoft Certified Professionals will exceed your expectations when you choose any of our services. Our highly talented team has spoken at many of the world&#8217;s most popular development conference and we give training on the newest technology. Read our blog for development tips, tricks and advice. We offer training on Telerik &amp; Progress Sitefinity, Kendo UI, Xamarin, and ASP.NET.</p>
<p><strong> </strong><strong>About Progress</strong></p>
<p><a href="http://cts.businesswire.com/ct/CT?id=smartlink&amp;url=http%3A%2F%2Fwww.progress.com&amp;esheet=51494545&amp;newsitemid=20170116005751&amp;lan=en-US&amp;anchor=Progress&amp;index=3&amp;md5=d46208cd020c2c4e4ac21dd1f877d5c8">Progress</a> (NASDAQ: PRGS) is a global leader in application development, empowering enterprises to build mission-critical business applications to succeed in an evolving business environment. With offerings spanning web, mobile and data for on-premise and cloud environments, Progress powers businesses worldwide, promoting success one application at a time. Learn about Progress at <a href="http://cts.businesswire.com/ct/CT?id=smartlink&amp;url=http%3A%2F%2Fwww.progress.com&amp;esheet=51494545&amp;newsitemid=20170116005751&amp;lan=en-US&amp;anchor=www.progress.com&amp;index=4&amp;md5=8783b8e8bec18de89cc64cbf0c690d34">www.progress.com</a> or 1-781-280-4000.</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/falafel-software-recognized-sitefinity-website-year/">Falafel Software Recognized for Sitefinity Website of the Year</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/falafel-software-recognized-sitefinity-website-year/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6243</post-id>	</item>
		<item>
		<title>On Sitefinity Custom Widget Caching</title>
		<link>https://blog.falafel.com/sitefinity-custom-widget-caching/</link>
		<comments>https://blog.falafel.com/sitefinity-custom-widget-caching/#respond</comments>
		<pubDate>Wed, 22 Feb 2017 15:00:31 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[Sitefinity]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Caching]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6211</guid>
		<description><![CDATA[<p>Sitefinity is Caching too Hard! If you&#8217;ve done software development for any length of time, you&#8217;ve likely run into a caching issue. Caching is difficult to get right, but it is so beneficial that we work with it in nearly everything we do. In the case of Sitefinity, it performs caching all over the place. As a result, many aspects of the Sitefinity experience are greatly improved. If you disabled caching for a Sitefinity site altogether, the site would slow down immensely. Sitefinity, by its nature of being a Content Management System, stores the bulk of its content in the...</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/sitefinity-custom-widget-caching/">On Sitefinity Custom Widget Caching</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<h2>Sitefinity is Caching too Hard!</h2>
<p>If you&#8217;ve done software development for any length of time, you&#8217;ve likely run into a caching issue. Caching is difficult to get right, but it is so beneficial that we work with it in nearly everything we do. In the case of Sitefinity, it performs caching all over the place. As a result, many aspects of the Sitefinity experience are greatly improved. If you disabled caching for a Sitefinity site altogether, the site would slow down immensely. Sitefinity, by its nature of being a Content Management System, stores the bulk of its content in the site&#8217;s backing data store (usually a database), so it would get very chatty if it couldn&#8217;t cache. However, like with all caching, we have the issue of cache invalidation to tackle. For built-in content widgets, this is already taken care of. But what if you have a custom content widget? You&#8217;ll quickly discover that a Sitefinity page, after rendered the first time, will not re-render even if said content is updated in the backend in some form. In this post I&#8217;ll show how you can enable automatic cache busting, so that custom widget caching is implemented correctly and your pages will always update when your content does.</p>
<h2>Example: Dynamic Content Widget Implementing Custom Widget Caching</h2>
<p>Here we have a controller working with a dynamic content item. This kind of controller implementation for custom widget caching can apply to any dynamic content type. The only thing that has to change is the type that you pass to the caching method. Let&#8217;s have a look and break it down.</p>
<pre class="crayon-plain-tag">using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Telerik.Sitefinity.Data;
using Telerik.Sitefinity.DynamicModules.Model;
using Telerik.Sitefinity.Services;
using Telerik.Sitefinity.Utilities.TypeConverters;
using Telerik.Sitefinity.Web;
using Telerik.Sitefinity.Web.UI.ContentUI.Contracts;

namespace SitefinityWebApp.Mvc.Controllers
{
    public class ExampleDynamicContentWidgetController : Controller, IHasCacheDependency
    {
        private Type DynamicContentType =&gt; TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.CustomModule.CustomType");

        public IList&lt;CacheDependencyKey&gt; GetCacheDependencyObjects()
        {
            return new List&lt;CacheDependencyKey&gt; { new CacheDependencyKey { Key = DynamicContentType.FullName, Type = typeof(DynamicContent) } };
        }

        protected void SubscribeToCacheDependency()
        {
            if (SystemManager.IsDesignMode || SystemManager.IsPreviewMode)
            {
                return;
            }
            IList&lt;CacheDependencyKey&gt; keys = GetCacheDependencyObjects();

            if (!SystemManager.CurrentHttpContext.Items.Contains(PageCacheDependencyKeys.PageData))
            {
                SystemManager.CurrentHttpContext.Items.Add(PageCacheDependencyKeys.PageData, new List&lt;CacheDependencyKey&gt;());
            }
            ((List&lt;CacheDependencyKey&gt;)SystemManager.CurrentHttpContext.Items[PageCacheDependencyKeys.PageData]).AddRange(keys);
        }

        public ActionResult Index()
        {
            SubscribeToCacheDependency();

            // Access your dynamic content here.

            return View("Default");
        }
    }
}</pre>
<p>The first thing you should note is that you have to make your controller implement the &#8220;IHasCacheDependency&#8221; interface and implement the &#8220;GetCacheDependencyObjects&#8221; method. This is the cornerstone of custom widget caching. Inside you see we are returning a single CacheDependencyKey, and tying it to our custom content type.</p>
<p>&#8220;SubscribeToCacheDependency&#8221; is the method you use to wire in any of your MVC actions to the caching mechanism. Note how in our Index action the first thing we do is call it.</p>
<p>That&#8217;s all there is to it! Now our widget will tell any pages it is on to re-run and get fresh data, instead of being stuck with stale cached date. Custom widget caching is really that simple!</p>
<h2>Example: News Content Widget Implementing Custom Widget Caching</h2>
<p>This will look much like the above example, but I wanted to demonstrate how to set up caching for a built-in Sitefinity content type.</p>
<pre class="crayon-plain-tag">using System.Collections.Generic;
using System.Web.Mvc;
using Telerik.Sitefinity.News.Model;
using Telerik.Sitefinity.Services;
using Telerik.Sitefinity.Data;
using Telerik.Sitefinity.Web;
using Telerik.Sitefinity.Web.UI.ContentUI.Contracts;

namespace SitefinityWebApp.Mvc.Controllers
{
    public class ExampleNewsWidgetController : Controller, IHasCacheDependency
    {
        public IList&lt;CacheDependencyKey&gt; GetCacheDependencyObjects()
        {
            return new List&lt;CacheDependencyKey&gt; { new CacheDependencyKey { Type = typeof(NewsItem) } };
        }

        protected void SubscribeToCacheDependency()
        {
            if (SystemManager.IsDesignMode || SystemManager.IsPreviewMode)
            {
                return;
            }
            IList&lt;CacheDependencyKey&gt; keys = GetCacheDependencyObjects();

            if (!SystemManager.CurrentHttpContext.Items.Contains(PageCacheDependencyKeys.PageData))
            {
                SystemManager.CurrentHttpContext.Items.Add(PageCacheDependencyKeys.PageData, new List&lt;CacheDependencyKey&gt;());
            }
            ((List&lt;CacheDependencyKey&gt;)SystemManager.CurrentHttpContext.Items[PageCacheDependencyKeys.PageData]).AddRange(keys);
        }

        public ActionResult Index(string category)
        {
            SubscribeToCacheDependency();

            // Access News here.

            return View();
        }
    }
}</pre>
<p>You see here that with the exception of GetCacheDependencyObjects creating a key whose type is &#8220;typeof(NewsItem)&#8221;, everything else plays out exactly the same. For built-in Sitefinity content types, you pass the type of the Model item (in this case, NewsItem) in order to configure it properly.</p>
<h2>Refactoring Custom Widget Caching Widgets to Share Code</h2>
<p>Since the two above are so similar, we definitely would want to refactor it. What we can do is create an abstract base class to make custom widget caching easy to implement going forward.</p>
<pre class="crayon-plain-tag">using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Telerik.Sitefinity.Data;
using Telerik.Sitefinity.DynamicModules.Model;
using Telerik.Sitefinity.News.Model;
using Telerik.Sitefinity.Services;
using Telerik.Sitefinity.Utilities.TypeConverters;
using Telerik.Sitefinity.Web;
using Telerik.Sitefinity.Web.UI.ContentUI.Contracts;

namespace SitefinityWebApp.Mvc.Controllers
{
    public abstract class CacheDependencyController : Controller, IHasCacheDependency
    {
        protected abstract Type CachedObjectType { get; }

        public IList&lt;CacheDependencyKey&gt; GetCacheDependencyObjects()
        {
            var key = CachedObjectType.ToString().StartsWith("Telerik.Sitefinity.DynamicTypes.Model")
                ? new CacheDependencyKey {Key = CachedObjectType.FullName, Type = typeof(DynamicContent)}
                : new CacheDependencyKey {Type = CachedObjectType};

            return new List&lt;CacheDependencyKey&gt; {key};
        }

        protected void SubscribeToCacheDependency()
        {
            if (SystemManager.IsDesignMode || SystemManager.IsPreviewMode)
            {
                return;
            }
            IList&lt;CacheDependencyKey&gt; keys = GetCacheDependencyObjects();
            if (!SystemManager.CurrentHttpContext.Items.Contains(PageCacheDependencyKeys.PageData))
            {
                SystemManager.CurrentHttpContext.Items.Add(PageCacheDependencyKeys.PageData, new List&lt;CacheDependencyKey&gt;());
            }
            ((List&lt;CacheDependencyKey&gt;)SystemManager.CurrentHttpContext.Items[PageCacheDependencyKeys.PageData]).AddRange(keys);
        }
    }

    public class ExampleDynamicContentWidgetController : CacheDependencyController
    {
        protected override Type CachedObjectType =&gt; TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.CustomModule.CustomType");

        public ActionResult Index()
        {
            SubscribeToCacheDependency();

            // Access your dynamic content here.

            return View("Default");
        }
    }

    public class ExampleNewsWidgetController : CacheDependencyController
    {
        protected override Type CachedObjectType =&gt; typeof(NewsItem);

        public ActionResult Index(string category)
        {
            SubscribeToCacheDependency();

            // Access News here.

            return View();
        }
    }
}</pre>
<p>Our base class now handles the boilerplate code, as well as deciding the correct kind of CacheDependencyKey to create and return. Look how easy it is to slap on to any custom widget! We inherit from the abstract class, implement the CachedObjectType, and call SubscribeToCacheDependency in any action we wish to cache. Custom Widget Caching is now incredibly simple!</p>
<p>If you have multiple types you wish to enable, then this particular refactor won&#8217;t work. It could easily be adjusted to accept a list of Types to cache, however. GetCacheDependencyObjects would simply have to be adjusted to return the list of types, instead of the list of a single type.</p>
<p>With this new tool in your arsenal, you can now continue to use the power of caching in your Sitefinity site, while making sure custom widget caching is in place to bust caches and prevent your site from serving stale content.</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/sitefinity-custom-widget-caching/">On Sitefinity Custom Widget Caching</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/sitefinity-custom-widget-caching/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6211</post-id>	</item>
		<item>
		<title>Disappointing Azure Cloud Failures</title>
		<link>https://blog.falafel.com/disappointing-azure-cloud-failures/</link>
		<comments>https://blog.falafel.com/disappointing-azure-cloud-failures/#comments</comments>
		<pubDate>Tue, 21 Feb 2017 19:01:19 +0000</pubDate>
		<dc:creator><![CDATA[Lino Tadros]]></dc:creator>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[Events]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[EventsXD]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6239</guid>
		<description><![CDATA[<p>I have been a big fan of the Microsoft Azure Cloud.  Here at Falafel we use it on dozens of projects for our valued customers and internally as well, but unfortunately Sunday Feb 19th 2017 was a bad day for the Azure cloud if your services, VMs, jobs, IoT and other services were running in their &#8220;West US 2&#8221; region. EventsXD One of our products, EventsXD experienced total failure around 5:00 am PST on Sunday while multiple conferences around the world were using the platform for their events.  Immediately, we were notified by our systems that connections to the Hosting...</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/disappointing-azure-cloud-failures/">Disappointing Azure Cloud Failures</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>I have been a big fan of the Microsoft Azure Cloud.  Here at <a href="http://www.falafel.com">Falafel </a>we use it on dozens of projects for our valued customers and internally as well, but unfortunately Sunday Feb 19th 2017 was a bad day for the Azure cloud if your services, VMs, jobs, IoT and other services were running in their &#8220;West US 2&#8221; region.</p>
<h2>EventsXD</h2>
<p>One of our products, EventsXD experienced total failure around 5:00 am PST on Sunday while multiple conferences around the world were using the platform for their events.  Immediately, we were notified by our systems that connections to the Hosting servers and SQL Servers in Azure were down.</p>
<h2>Azure Cloud Failure</h2>
<p>I opened a critical support ticket with Microsoft around 6:00 am PST, gladly received a reply at 6:15 am (very fast) that Engineering is looking into it.</p>
<p>At this time, we started received emails and calls from angry customers that their event is down and none of the attendees or the organizers can access the event on their mobile device.</p>
<p>It took 6.5 hours for Azure to restore the services on &#8220;West US 2&#8221;, by that time several clients notified us that they would like a refund for their events and I am pretty sure they will not be using EventsXD again in the near future.</p>
<h2>Lack of Redundancy</h2>
<p>EventsXD has over 10,000 events running on its platform worldwide.  We thought we were in good hands with Microsoft Azure with adequate &#8220;<strong>Redundancy</strong>&#8221; and solid infrastructure.</p>
<p>Even though the support was excellent as far as timing, they did not provide ANY valuable information regarding how could that possibly happen in a Cloud platform that drives itself on &#8220;Redundancy&#8221; and solid infrastructure.</p>
<p>To say the least, we are very concerned about our investment and reliance on the Azure Cloud after this instance.  This is the 3rd time in 18 months that Azure fails and causes catastrophic results to critical apps running on the platform.</p>
<h2>Difficult Decision</h2>
<p>Is it time to move EventsXD and other projects to <a href="https://aws.amazon.com/">AWS </a>or <a href="https://cloud.google.com/">Google Cloud</a>?</p>
<p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/disappointing-azure-cloud-failures/">Disappointing Azure Cloud Failures</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/disappointing-azure-cloud-failures/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6239</post-id>	</item>
		<item>
		<title>Dynamic Content Detail Widget Templates in Sitefinity</title>
		<link>https://blog.falafel.com/dynamic-content-detail-widget-sitefinity/</link>
		<comments>https://blog.falafel.com/dynamic-content-detail-widget-sitefinity/#respond</comments>
		<pubDate>Wed, 08 Feb 2017 15:00:37 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Sitefinity]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[asp.net]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6207</guid>
		<description><![CDATA[<p>Getting to Dynamic Content Data in Custom Code Behind In a previous post, I went over how you can easily create a custom code-behind C# class for any Widget Template in Sitefinity. Give that post a quick once-over, as this post builds upon that one. For built-in Sitefinity content items, accessing the data is pretty straightforward (see the previously-linked post): You grab the container, iterate over the items (even in the case of a single detail item), and then work with the data to make customizations to the page. For Dynamic Content Detail Widget templates, however, things work differently. You...</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/dynamic-content-detail-widget-sitefinity/">Dynamic Content Detail Widget Templates in Sitefinity</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<h2>Getting to Dynamic Content Data in Custom Code Behind</h2>
<p>In a <a href="https://blog.falafel.com/widget-template-code-customized-easy/">previous post</a>, I went over how you can easily create a custom code-behind C# class for any Widget Template in Sitefinity. Give that post a quick once-over, as this post builds upon that one. For built-in Sitefinity content items, accessing the data is pretty straightforward (see the previously-linked post): You grab the container, iterate over the items (even in the case of a single detail item), and then work with the data to make customizations to the page. For Dynamic Content Detail Widget templates, however, things work differently. You can still get access to your data, but if you observe the content of a detail widget template for dynamic content, you&#8217;ll will find only a DynamicDetailContainer to work with. How do you access your item? Let&#8217;s find out!</p>
<h2>Binding to DynamicDetailContainer&#8217;s DataBound Event</h2>
<p>This first step is more-or-less identical to how we&#8217;ve done this before. We find our DynamicDetailContainer and assign a method to its DataBound event:</p>
<pre class="crayon-plain-tag">using System;
using System.Linq;
using System.Web.UI;
using Telerik.Sitefinity.DynamicModules.Model;
using Telerik.Sitefinity.DynamicModules.Web.UI.Frontend;
using Telerik.Sitefinity.Model;

namespace SitefinityWebApp.Custom
{
    public class CustomCodeBehind : UserControl
    {
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            DynamicDetailContainer detailContainer = (DynamicDetailContainer)FindControl("detailContainer");
            if (detailContainer != null)
            {
                detailContainer.DataBound += DetailContainerDataBound;
            }
        }

        private void DetailContainerDataBound(object sender, EventArgs e)
        {
            throw new NotImplementedException();
        }
    }
}</pre>
<p>You can see how similar this is to the one we&#8217;ve created before! The only difference in the case of a Dynamic Content Detail Widget&#8217;s DynamicDetailContainer event is that we bind to a method whose parameters are of type &#8220;object&#8221; and &#8220;EventArgs.&#8221; Previously we bound to a method whose second parameter was &#8220;RadListViewItemEventArgs.&#8221;</p>
<h2>Getting to Your DynamicContent Object</h2>
<p>Now that we&#8217;re in our DataBound method, we need to reach out to our object we&#8217;re binding to. Since this container doesn&#8217;t iterate on DataBound, we have to access the entire collection of bound objects. For a Dynamic Content Detail Widget, this collection will always have just one object in play. The DynamicDetailContainer will possess this single-item collection, and the container itself is passed to the event via the &#8220;sender&#8221; parameter. Here&#8217;s what a complete example looks like:</p>
<pre class="crayon-plain-tag">using System;
using System.Linq;
using System.Web.UI;
using Telerik.Sitefinity.DynamicModules.Model;
using Telerik.Sitefinity.DynamicModules.Web.UI.Frontend;
using Telerik.Sitefinity.Model;

namespace SitefinityWebApp.Custom
{
    public class CustomCodeBehind : UserControl
    {
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            DynamicDetailContainer detailContainer = (DynamicDetailContainer)FindControl("detailContainer");
            if (detailContainer != null)
            {
                detailContainer.DataBound += DetailContainerDataBound;
            }
        }

        private void DetailContainerDataBound(object sender, EventArgs e)
        {
            DynamicDetailContainer detailContainer = (DynamicDetailContainer)sender;
            DynamicContent[] dynamicItems = (DynamicContent[])detailContainer.DataSource;
            DynamicContent dynamicItem = dynamicItems.FirstOrDefault();
            if (dynamicItem == null)
            {
                return;
            }
            
            // Perform customizations with dynamicItem here.
        }
    }
}</pre>
<p>We first cast &#8220;sender&#8221; to the type DynamicDetailContainer. Dynamic Content Detail Widget&#8217;s DetailContainer DataBound event always passes this. This object has a &#8220;DataSource&#8221; property where the collection of DynamicContent items, stored as an array, can be found. From there it&#8217;s a simple matter of LINQing out our single object, verifying we got it, then performing whatever customizations we desire based off of our bound object.</p>
<h2>Working with your DynamicContent Object</h2>
<p>As expected, the Dynamic Content Detail Widget&#8217;s DetailContainer works with the live, published version of the item. It would be really weird if it didn&#8217;t! Sitefinity binds this item to the container to show the live, published data, and now the power&#8217;s in your hands as well. You can work with this item the way you would work with DynamicContent items in any other programming context: Fetch custom fields, get related data, etc. You could technically re-fetch it too, using the given ID, but since the container already has the object for you that would be redundant.</p>
<p>And that&#8217;s it! This functionality took me a little digging to find, but now you can find it easily here. Working with Dynamic Content Detail Widget code-behinds is as easy as working with any widget template code-behind, once you know how to get to the item. Now you do!</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/dynamic-content-detail-widget-sitefinity/">Dynamic Content Detail Widget Templates in Sitefinity</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/dynamic-content-detail-widget-sitefinity/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6207</post-id>	</item>
		<item>
		<title>Using Google Services in UWP C# Apps – Part 2</title>
		<link>https://blog.falafel.com/using-google-services-uwp-c-apps-part-2/</link>
		<comments>https://blog.falafel.com/using-google-services-uwp-c-apps-part-2/#comments</comments>
		<pubDate>Tue, 07 Feb 2017 17:03:03 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[Cloud Platform]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Cryptography]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>
		<category><![CDATA[JWT]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[UWP]]></category>
		<category><![CDATA[X509Certificate2]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6234</guid>
		<description><![CDATA[<p>This is post 17 of 17 in the series &#8220;Google Cloud for the .NET Developer&#8221; We previously looked at how you can use the WebAuthenticationBroker to allow end users to authorize a UWP app to access their Google account information. In this post we’ll complete the sample by describing how to authorize a UWP app to access Google Cloud Product services. To demonstrate this, we’ll recreate the ASP.NET MVC sample that logins in a user, grabs their profile image, and uploads that image to Google Storage. However, just like in our previous sample, we don’t have any helper libraries we...</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/using-google-services-uwp-c-apps-part-2/">Using Google Services in UWP C# Apps – Part 2</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<aside class="wp-post-series-box series-google-cloud-for-the-net-developer">
	<p class="wp-post-series-name">
		This is post 17 of 17 in the series <em>&ldquo;Google Cloud for the .NET Developer&rdquo;</em>	</p>

	
	</aside>
<p>We previously looked at how you can use the WebAuthenticationBroker to allow end users to authorize a UWP app to access their Google account information. In this post we’ll complete the sample by describing how to authorize a UWP app to access Google Cloud Product services.</p>
<p>To demonstrate this, we’ll recreate the ASP.NET MVC sample that logins in a user, grabs their profile image, and uploads that image to Google Storage.</p>
<p>However, just like in our previous sample, we don’t have any helper libraries we can use, because as of this writing the Google Cloud SDK does not yet natively support UWP. Fortunately, we can always access the <a href="https://cloud.google.com/storage/docs/json_api/v1/">services via REST</a>, so let&#8217;s get to it.</p>
<h2>Authorization Workflow</h2>
<p>Just like in our MVC sample, we need a way to authorize our app to access the services in our GCP account so that it can make the appropriate changes, in this case, uploading an image to Google Storage.</p>
<p>However, unlike our MVC sample, we are unable to use the same <a href="https://developers.google.com/identity/protocols/OAuth2WebServer">Web Server OAuth Workflow</a> because it would require that we issue a POST containing the client secret, and this request could be hijacked by a malicious user, compromising our security.</p>
<p>Instead, we need to use a different <a href="https://developers.google.com/identity/protocols/OAuth2ServiceAccount?hl=en_US">OAuth workflow for Service Accounts</a> which uses a JSON Web Token (JWT) to authorize the request. The JWT contains the scope of your request, and needs to be signed with your private key, which is issued when you create credentials in the <a href="https://console.cloud.google.com/apis/credentials">Google API Console</a>.</p>
<p>Recall that when you create a Service Account in the console (in this case we want to use the option for P12), you are immediately served a file containing your private key.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-Service-Account.png" rel="prettyPhoto[gallery-3UxH]"><img class="alignnone size-medium wp-image-6145" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-Service-Account-300x286.png" alt="Google-Cloud-Platform-Create-Service-Account" width="300" height="286" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-Service-Account-300x286.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-Service-Account-768x733.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-Service-Account.png 947w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>This is the only time that key is available, so be sure to keep that key safe, or you will have to delete it and create a new one.</p>
<p>Once you’ve created the JWT, having signed it with your private key, you simply POST this request to the Google authorization endpoint, and you will be returned a response containing a Bearer token that you can use to make authorized requests to the scopes you requested in the JWT.</p>
<p>Before we look at the code, let’s take a moment to review an important consideration regarding security for your app.</p>
<h2>Security Considerations</h2>
<p>Because the request needs to be signed, your app must have access to the file containing your private key, in this case the P12 file issued when you created the Service Account you’ll be using to authenticate your app.</p>
<p>Although you can simply include this file in your app, you probably don’t want to do this for any scenario other than testing locally. Distributing your app with the key file means anyone could use it to sign requests on behalf of your app!</p>
<p>A slightly better idea may be to embed the file as a resource into your app, so that it’s not freely available as a separate file. This is what we’re doing in this example. However, a malicious user could certainly still decompile your app and retrieve the key that way. Encryption and obfuscation is probably a good idea, especially in specific scenarios, such as internal business apps, where you can control access to devices where your app is deployed.</p>
<p>Ideally, however, you probably want to setup a proxy web service to handle requests to the GCP service, and use the server authentication from our previous example to perform the GCP service operations. This way your server can be authorized entirely outside your app, protecting your key from being stolen and giving you full control of your apps content workflow.</p>
<p>That being said, I am not a security expert by any means, and would love to hear thoughts from how to best protect a UWP app from others in the comments. This sample is meant only to serve as a simple example of accessing GCP in a UWP app, so please use with care.</p>
<p>Now that we understand the workflow and security needs, let’s dive into the code!</p>
<h2>Creating a JWT in UWP Apps</h2>
<p>The trickiest part of putting this sample together was definitely creating the JWT token, because the token has to be signed, and cryptography isn’t something I personally know a lot about.</p>
<p>Fortunately, I found a helpful sample from developer Ilya Melamed who wrote a post about <a href="https://zavitax.wordpress.com/2012/12/17/logging-in-with-google-service-account-in-c-jwt/">Authenticating with Google Service Account in C# (JWT)</a>. This sample is for the full .NET framework (such as WPF apps) and many of the classes used are not available for UWP. However, it was a useful starting point which I used to expand to UWP.</p>
<h3>X509Certificate2</h3>
<p>The key part of Ilya’s sample is the use of the X509Certificate2 class which can load the P12 key file from Google. Although UWP does not have this class natively in the framework, there is a nuget package available which adds these classes: <a href="https://www.nuget.org/packages/System.Security.Cryptography.X509Certificates">System.Security.Cryptography.X509Certificates</a></p>
<p>With this we’ll be able to open the P12 key and use it to sign our JWT, so in my sample project I’ve added that key file as an embedded resource:</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/02/Google-Cloud-Platform-p12-key.png" rel="prettyPhoto[gallery-3UxH]"><img class="alignnone size-medium wp-image-6235" src="https://blog.falafel.com/wp-content/uploads/2017/02/Google-Cloud-Platform-p12-key-181x300.png" alt="Google-Cloud-Platform-p12-key" width="181" height="300" srcset="https://blog.falafel.com/wp-content/uploads/2017/02/Google-Cloud-Platform-p12-key-181x300.png 181w, https://blog.falafel.com/wp-content/uploads/2017/02/Google-Cloud-Platform-p12-key-616x1024.png 616w, https://blog.falafel.com/wp-content/uploads/2017/02/Google-Cloud-Platform-p12-key.png 700w" sizes="(max-width: 181px) 100vw, 181px" /></a></p>
<p>To open the file we extract it from the assembly as a stream, and read the contents as bytes:</p>
<pre class="crayon-plain-tag">var assembly = this.GetType().GetTypeInfo().Assembly;
    var stream = assembly.GetManifestResourceStream("GoogleUwpTestApp.Falafel-Test-Project-232e85f0df81.p12");
    using (var streamReader = new BinaryReader(stream))
    {
        var bytes = streamReader.ReadBytes((int) stream.Length);
                // ...
    }</pre>
<p>This will eventually be passed to the X509Certificate2 constructor, which accepts those bytes and the password, which is “notasecret” for GCP certificates:</p>
<pre class="crayon-plain-tag">var certificate = new X509Certificate2(certificateBytes, "notasecret", X509KeyStorageFlags.Exportable);</pre>
<p>Now that we have a way to sign our token, let’s create it!</p>
<h3>Creating the Token</h3>
<p>The header is the same for all requests, indicating the type and signing algorithm:</p>
<pre class="crayon-plain-tag">var header = new { typ = "JWT", alg = "RS256" };</pre>
<p>Next we need to create the claimset, which contains our client ID, requested scopes, and other details described in the <a href="https://developers.google.com/identity/protocols/OAuth2ServiceAccount#creatingjwt">Google OAuth documentation</a>:</p>
<pre class="crayon-plain-tag">var times = GetExpiryAndIssueDate();
var claimset = new
{
    iss = clientID,
    scope = scope,
    aud = "https://www.googleapis.com/oauth2/v4/token",
    iat = times[0],
    exp = times[1],
};</pre>
<p>These components of the JWT then need to be Base64 encoded:</p>
<pre class="crayon-plain-tag">// encoded header
            var headerSerialized = JsonConvert.SerializeObject(header);
            var headerBytes = Encoding.UTF8.GetBytes(headerSerialized);
            var headerEncoded = Convert.ToBase64String(headerBytes);

            // encoded claimset
            var claimsetSerialized = JsonConvert.SerializeObject(claimset);
            var claimsetBytes = Encoding.UTF8.GetBytes(claimsetSerialized);
            var claimsetEncoded = Convert.ToBase64String(claimsetBytes);

            // input
            var input = headerEncoded + "." + claimsetEncoded;
            var inputBytes = Encoding.UTF8.GetBytes(input);</pre>
<p>And finally, we use the certificate we opened to sign the token, putting it all together to get the final JWT:</p>
<pre class="crayon-plain-tag">// signature
            string signatureEncoded;
            try
            {
                var signatureBytes = certificate.GetRSAPrivateKey().SignData(inputBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
                signatureEncoded = Convert.ToBase64String(signatureBytes);
            }
            catch (Exception ex)
            {
                signatureEncoded = string.Empty;
            }

            // jwt
            var jwt = headerEncoded + "." + claimsetEncoded + "." + signatureEncoded;</pre>
<p>Now that we have our token, we can issue a POST to the Google authorization endpoint:</p>
<pre class="crayon-plain-tag">// wrap parameters in a Form object
            var content = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair&lt;string, string&gt;("assertion", jwt),
                new KeyValuePair&lt;string, string&gt;("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer")
            });

            // the url to send the POST request (from the google docs)
            var postUrl = "https://www.googleapis.com/oauth2/v4/token";

            // submit the request
            var client = new HttpClient();
            var result = await client.PostAsync(postUrl, content);
            var str = await result.Content.ReadAsStringAsync();

            dynamic parsedResult = JsonConvert.DeserializeObject(str);
            return result == null ? string.Empty : parsedResult.access_token;</pre>
<p>And if we did everything right, we’ll get back the access token for our app, which we&#8217;ll use to authorize subsequent requests to our GCP services.</p>
<p>Here&#8217;s the complete GoogleJsonWebTokenHelper class for UWP:</p>
<pre class="crayon-plain-tag">using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace GoogleUwpTestApp.Google
{
    public class GoogleJsonWebTokenHelper
    {
        private readonly string clientID;
        private readonly string scope;

        public GoogleJsonWebTokenHelper(string clientID, string scope)
        {
            this.clientID = clientID;
            this.scope = scope;
        }

        public async Task&lt;string&gt; GetAccessToken(string certificateFilePath)
        {
            // certificate
            var certificate = new X509Certificate2(certificateFilePath, "notasecret", X509KeyStorageFlags.Exportable);
            return await GetAccessTokenInternal(certificate);
        }

        public async Task&lt;string&gt; GetAccessToken(byte[] certificateBytes)
        {
            // certificate
            var certificate = new X509Certificate2(certificateBytes, "notasecret", X509KeyStorageFlags.Exportable);
            return await GetAccessTokenInternal(certificate);
        }

        private async Task&lt;string&gt; GetAccessTokenInternal(X509Certificate2 certificate)
        { 
            // header
            var header = new { typ = "JWT", alg = "RS256" };

            // claimset
            var times = GetExpiryAndIssueDate();
            var claimset = new
            {
                iss = clientID,
                scope = scope,
                aud = "https://www.googleapis.com/oauth2/v4/token",
                iat = times[0],
                exp = times[1],
            };

            // encoded header
            var headerSerialized = JsonConvert.SerializeObject(header);
            var headerBytes = Encoding.UTF8.GetBytes(headerSerialized);
            var headerEncoded = Convert.ToBase64String(headerBytes);

            // encoded claimset
            var claimsetSerialized = JsonConvert.SerializeObject(claimset);
            var claimsetBytes = Encoding.UTF8.GetBytes(claimsetSerialized);
            var claimsetEncoded = Convert.ToBase64String(claimsetBytes);

            // input
            var input = headerEncoded + "." + claimsetEncoded;
            var inputBytes = Encoding.UTF8.GetBytes(input);

            // signature
            string signatureEncoded;
            try
            {
                var signatureBytes = certificate.GetRSAPrivateKey().SignData(inputBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
                signatureEncoded = Convert.ToBase64String(signatureBytes);
            }
            catch (Exception ex)
            {
                signatureEncoded = string.Empty;
            }

            // jwt
            var jwt = headerEncoded + "." + claimsetEncoded + "." + signatureEncoded;

            // wrap parameters in a Form object
            var content = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair&lt;string, string&gt;("assertion", jwt),
                new KeyValuePair&lt;string, string&gt;("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer")
            });

            // the url to send the POST request (from the google docs)
            var postUrl = "https://www.googleapis.com/oauth2/v4/token";

            // submit the request
            var client = new HttpClient();
            var result = await client.PostAsync(postUrl, content);
            var str = await result.Content.ReadAsStringAsync();

            dynamic parsedResult = JsonConvert.DeserializeObject(str);
            return result == null ? string.Empty : parsedResult.access_token;
        }

        private int[] GetExpiryAndIssueDate()
        {
            var utc0 = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
            var issueTime = DateTime.UtcNow;

            var iat = (int) issueTime.Subtract(utc0).TotalSeconds;
            var exp = (int) issueTime.AddMinutes(55).Subtract(utc0).TotalSeconds;

            return new[] { iat, exp };
        }
    }
}</pre>
<p>&nbsp;</p>
<h2>Uploading an Image</h2>
<p>Now that we have the token we can proceed to <a href="https://cloud.google.com/storage/docs/json_api/v1/how-tos/simple-upload">issue a simple POST request</a> with the image contents we retrieve from the user, including the token in the header:</p>
<pre class="crayon-plain-tag">public async Task UploadImage(string url, string filename, string bucketName)
        {
            var client = new HttpClient();
            var resultStream = await client.GetStreamAsync(url);

            Byte[] bytes;
            using (var memoryStream = new MemoryStream())
            {
                resultStream.CopyTo(memoryStream);
                bytes = memoryStream.ToArray();
            }


            client.DefaultRequestHeaders.Add("Authorization", "Bearer  " + access_token);
            var uploadUri = string.Format("https://www.googleapis.com/upload/storage/v1/b/{0}/o?uploadType=media&amp;name={1}&amp;predefinedAcl=publicRead", bucketName, filename);

            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uploadUri);
            request.Content = new ByteArrayContent(bytes);
            request.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
            request.Content.Headers.ContentLength = bytes.Length;

            HttpResponseMessage response = await client.SendAsync(request);
            var result = await response.Content.ReadAsStringAsync();
        }</pre>
<p>The result is an image uploaded to the storage bucket, which we use to refresh the list, and now have a new profile image added to the ListView:</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/02/Google-Cloud-Platform-UWP-App-Profile-Images.png" rel="prettyPhoto[gallery-3UxH]"><img class="alignnone size-medium wp-image-6236" src="https://blog.falafel.com/wp-content/uploads/2017/02/Google-Cloud-Platform-UWP-App-Profile-Images-300x253.png" alt="Google-Cloud-Platform-UWP-App-Profile-Images" width="300" height="253" srcset="https://blog.falafel.com/wp-content/uploads/2017/02/Google-Cloud-Platform-UWP-App-Profile-Images-300x253.png 300w, https://blog.falafel.com/wp-content/uploads/2017/02/Google-Cloud-Platform-UWP-App-Profile-Images-768x647.png 768w, https://blog.falafel.com/wp-content/uploads/2017/02/Google-Cloud-Platform-UWP-App-Profile-Images-1024x863.png 1024w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Retrieving the items from Google storage is done similarly to our MVC sample; we simply query the rest API, sending the same bearer token we already retrieved:</p>
<pre class="crayon-plain-tag">public async Task&lt;StorageModel&gt; GetStorageImages(string bucketName)
        {
            var client = new HttpClient();
            client.DefaultRequestHeaders.Add("Authorization", "Bearer  " + access_token);
            var bucketUri = string.Format("https://www.googleapis.com/storage/v1/b/{0}/o", "falafel-test-profile-images");

            var resultJson = await client.GetStringAsync(bucketUri);
            var storageResult = JsonConvert.DeserializeObject&lt;StorageModel&gt;(resultJson);

            return storageResult;
        }</pre>
<p>In this case, StorageModel is just a simple C# class that encapsulates the JSON result from the call:</p>
<pre class="crayon-plain-tag">public class Item
    {
        public string kind { get; set; }
        public string id { get; set; }
        public string selfLink { get; set; }
        public string name { get; set; }
        public string bucket { get; set; }
        public string generation { get; set; }
        public string metageneration { get; set; }
        public string contentType { get; set; }
        public string timeCreated { get; set; }
        public string updated { get; set; }
        public string storageClass { get; set; }
        public string timeStorageClassUpdated { get; set; }
        public string size { get; set; }
        public string md5Hash { get; set; }
        public string mediaLink { get; set; }
        public string crc32c { get; set; }
        public string etag { get; set; }
    }

    public class StorageModel
    {
        public string kind { get; set; }
        public List&lt;Item&gt; items { get; set; }
    }</pre>
<p>That&#8217;s all there is to it!</p>
<h2>Wrapping Up</h2>
<p>Although the Google Cloud SDK doesn&#8217;t yet have native support for UWP apps, it is still possible to perform any of the various operations for both Service and User accounts using plain old REST commands. Authorizing your app to access GCP Services via Service Account takes a bit more work, and you do want to be careful with your certificates, but it&#8217;s absolutely possible with a little extra work.</p>
<p>Hopefully we&#8217;ll start to see some UWP support in the coming months, but in the meantime, as always I hope this was helpful, and thanks for reading!</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/using-google-services-uwp-c-apps-part-2/">Using Google Services in UWP C# Apps – Part 2</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/using-google-services-uwp-c-apps-part-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6234</post-id>	</item>
		<item>
		<title>Using Google Services in UWP C# Apps – Part 1</title>
		<link>https://blog.falafel.com/using-google-services-in-uwp-c-apps-part-1/</link>
		<comments>https://blog.falafel.com/using-google-services-in-uwp-c-apps-part-1/#respond</comments>
		<pubDate>Mon, 06 Feb 2017 21:07:37 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[Cloud Platform]]></category>
		<category><![CDATA[Authentication]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[OAuth]]></category>
		<category><![CDATA[UWP]]></category>
		<category><![CDATA[Windows 10]]></category>
		<category><![CDATA[XAML]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6215</guid>
		<description><![CDATA[<p>This is post 16 of 17 in the series &#8220;Google Cloud for the .NET Developer&#8221; It’s no secret that I love Windows, and especially writing UWP apps for Windows using C#. In fact I’ve written a bit about creating UWP apps in the past, so as a fan of UWP, I wanted to explore how one can leverage the Google Cloud Platform and other Google services in Windows apps. Unfortunately, as of this writing, Google does not officially support UWP. However, this is not to say you cannot USE Google services in your app; it only means that the SDKs available to...</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/using-google-services-in-uwp-c-apps-part-1/">Using Google Services in UWP C# Apps – Part 1</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<aside class="wp-post-series-box series-google-cloud-for-the-net-developer">
	<p class="wp-post-series-name">
		This is post 16 of 17 in the series <em>&ldquo;Google Cloud for the .NET Developer&rdquo;</em>	</p>

	
	</aside>
<p>It’s no secret that I love Windows, and especially writing UWP apps for Windows using C#. In fact I’ve written a bit about <a href="https://blog.falafel.com/?post_series=developing-for-windows-10">creating UWP apps</a> in the past, so as a fan of UWP, I wanted to explore how one can leverage the Google Cloud Platform and other Google services in Windows apps.</p>
<p>Unfortunately, as of this writing, Google<a href="https://github.com/google/google-api-dotnet-client/pull/852"> does not officially support UWP</a>. However, this is not to say you cannot USE Google services in your app; it only means that the SDKs available to simplify accessing these services have not yet been updated to support the UWP platform.</p>
<p>In short, we have to do all the work ourselves!</p>
<p>Fortunately, there’s a few resources out there that I’ve compiled here to get you started. Let’s start with a simple example: authorizing an app to access a Google user account.</p>
<h2>Google Samples for Windows and UWP</h2>
<p>A good place to start is going to be on Github, where there is a collection of <a href="https://github.com/googlesamples/oauth-apps-for-windows">OAuth samples for Windows</a>. These apps show you how to authenticate users in different Windows apps, including console apps, WPF, and UWP, which is what we’re interested in today.</p>
<p>The <a href="https://github.com/googlesamples/oauth-apps-for-windows/blob/master/OAuthUniversalApp/README.md">README</a> for the UWP app describes the project in more detail, including how to get started, so I’ll leave it to the reader to check that out. Instead, I want to review a few important points about how this project is setup.</p>
<h3>Create OAuth Credentials</h3>
<p>Before getting started you want to make sure you have <a href="https://support.google.com/googleapi/answer/6158849?hl=en#installedapplications&amp;ios">created OAUTH credentials</a> for your application, as you’ll need a Client ID specifically setup for this authorization method for any of this to work.</p>
<p>The <a href="https://github.com/googlesamples/oauth-apps-for-windows/blob/master/OAuthUniversalApp/README.md">README</a> for the sample specifies that you need to follow the instructions for the installed app <a href="https://support.google.com/googleapi/answer/6158849?hl=en#installedapplications&amp;ios">specifically for iOS</a>, as this works for UWP apps as well. So create your OAUTH key and note your Client ID which you’ll need to update in the sample.</p>
<h3>Authorization Workflow</h3>
<p>The way this sample was written is quite similar to the sample we looked at previously for authorizing a website to use a Google user account. Essentially, an authorization URL is constructed (using client id, and some other required parameters) and the user is redirected to that page via the browser.</p>
<p>This means the app will actually launch the browser on the device, taking the user out of the app to complete the login process.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-OAuth-Sample-Launch-Browser.png" rel="prettyPhoto[gallery-ELm7]"><img class="alignnone size-medium wp-image-6216" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-OAuth-Sample-Launch-Browser-300x223.png" alt="Google-Cloud-Platform-UWP-OAuth-Sample-Launch-Browser" width="300" height="223" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-OAuth-Sample-Launch-Browser-300x223.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-OAuth-Sample-Launch-Browser-768x570.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-OAuth-Sample-Launch-Browser-1024x760.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-OAuth-Sample-Launch-Browser.png 1578w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>So let’s take a look at the code that accomplishes this:</p>
<pre class="crayon-plain-tag">/// &lt;summary&gt;
        /// Starts an OAuth 2.0 Authorization Request.
        /// &lt;/summary&gt;
        private void button_Click(object sender, RoutedEventArgs e)
        {
            // Generates state and PKCE values.
            string state = randomDataBase64url(32);
            string code_verifier = randomDataBase64url(32);
            string code_challenge = base64urlencodeNoPadding(sha256(code_verifier));
            const string code_challenge_method = "S256";

            // Stores the state and code_verifier values into local settings.
            // Member variables of this class may not be present when the app is resumed with the
            // authorization response, so LocalSettings can be used to persist any needed values.
            ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
            localSettings.Values["state"] = state;
            localSettings.Values["code_verifier"] = code_verifier;

            // Creates the OAuth 2.0 authorization request.
            string authorizationRequest = string.Format("{0}?response_type=code&amp;scope=openid%20profile&amp;redirect_uri={1}&amp;client_id={2}&amp;state={3}&amp;code_challenge={4}&amp;code_challenge_method={5}",
                authorizationEndpoint,
                System.Uri.EscapeDataString(redirectURI),
                clientID,
                state,
                code_challenge,
                code_challenge_method);

            output("Opening authorization request URI: " + authorizationRequest);

            // Opens the Authorization URI in the browser.
            var success = Windows.System.Launcher.LaunchUriAsync(new Uri(authorizationRequest));
        }</pre>
<p>Although the process is similar to the web workflow we looked at for the MVC sample, we are using a slightly different URL and parameters to indicate that the request is coming from a device. For security reasons, we can’t embed our client secret in the app, because it could be sniffed over the wire when we POST it to exchange it for the access token.</p>
<p>Instead, the UWP sample leverages <a href="https://tools.ietf.org/html/rfc7636">Proof Key Code Exchange (PKCE)</a> to validate the request. Essentially, rather than sending the client secret, we hash a code in the app so that the server can know that the request came from us.</p>
<p>If you want to know more about this setup there’s a great description of the process on the Auth0 website: <a href="https://auth0.com/docs/api-auth/grant/authorization-code-pkce">https://auth0.com/docs/api-auth/grant/authorization-code-pkce</a></p>
<p>Once the user completes the login, they are redirected to our app via the protocol activation defined in the manifest:</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-Manifest-Capabilities.png" rel="prettyPhoto[gallery-ELm7]"><img class="alignnone size-medium wp-image-6217" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-Manifest-Capabilities-300x173.png" alt="Google-Cloud-Platform-UWP-Manifest-Capabilities" width="300" height="173" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-Manifest-Capabilities-300x173.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-Manifest-Capabilities-768x444.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-Manifest-Capabilities-1024x592.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-Manifest-Capabilities.png 1553w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Launching the app registers this protocol on the device so that when the browser redirects the user to it the app is launched, passing along the OAUTH parameters so we can continue the login process.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-Protocol-Activation.png" rel="prettyPhoto[gallery-ELm7]"><img class="alignnone size-medium wp-image-6218" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-Protocol-Activation-275x300.png" alt="Google-Cloud-Platform-UWP-Protocol-Activation" width="275" height="300" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-Protocol-Activation-275x300.png 275w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-Protocol-Activation.png 554w" sizes="(max-width: 275px) 100vw, 275px" /></a></p>
<p>In this case, launching the app again triggers the OnNavigatedTo event, which checks for the presence of a URI parameter, which is then parsed to validate the result so far:</p>
<pre class="crayon-plain-tag">/// &lt;summary&gt;
        /// Processes the OAuth 2.0 Authorization Response
        /// &lt;/summary&gt;
        /// &lt;param name="e"&gt;&lt;/param&gt;
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            if (e.Parameter is Uri)
            {
                // Gets URI from navigation parameters.
                Uri authorizationResponse = (Uri) e.Parameter;
                string queryString = authorizationResponse.Query;
                output("MainPage received authorizationResponse: " + authorizationResponse);

                // Parses URI params into a dictionary
                // ref: http://stackoverflow.com/a/11957114/72176
                Dictionary&lt;string, string&gt; queryStringParams =
                        queryString.Substring(1).Split('&amp;')
                             .ToDictionary(c =&gt; c.Split('=')[0],
                                           c =&gt; Uri.UnescapeDataString(c.Split('=')[1]));

                if (queryStringParams.ContainsKey("error"))
                {
                    output(String.Format("OAuth authorization error: {0}.", queryStringParams["error"]));
                    return;
                }

                if (!queryStringParams.ContainsKey("code")
                    || !queryStringParams.ContainsKey("state"))
                {
                    output("Malformed authorization response. " + queryString);
                    return;
                }

                // Gets the Authorization code &amp; state
                string code = queryStringParams["code"];
                string incoming_state = queryStringParams["state"];

                // Retrieves the expected 'state' value from local settings (saved when the request was made).
                ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
                string expected_state = (String) localSettings.Values["state"];

                // Compares the receieved state to the expected value, to ensure that
                // this app made the request which resulted in authorization
                if (incoming_state != expected_state)
                {
                    output(String.Format("Received request with invalid state ({0})", incoming_state));
                    return;
                }

                // Resets expected state value to avoid a replay attack.
                localSettings.Values["state"] = null;

                // Authorization Code is now ready to use!
                output(Environment.NewLine + "Authorization code: " + code);

                string code_verifier = (String) localSettings.Values["code_verifier"];
                performCodeExchangeAsync(code, code_verifier);
            }
            else
            {
                Debug.WriteLine(e.Parameter);
            }
        }</pre>
<p>If everything checks out, we can finally exchange the resulting code for an access token, being sure to pass along the original code verifier so that the server can validate the request. Here is what that code looks like:</p>
<pre class="crayon-plain-tag">async void performCodeExchangeAsync(string code, string code_verifier)
        {
            // Builds the Token request
            string tokenRequestBody = string.Format("code={0}&amp;redirect_uri={1}&amp;client_id={2}&amp;code_verifier={3}&amp;scope=&amp;grant_type=authorization_code",
                code,
                System.Uri.EscapeDataString(redirectURI),
                clientID,
                code_verifier
                );
            StringContent content = new StringContent(tokenRequestBody, Encoding.UTF8, "application/x-www-form-urlencoded");

            // Performs the authorization code exchange.
            HttpClientHandler handler = new HttpClientHandler();
            handler.AllowAutoRedirect = true;
            HttpClient client = new HttpClient(handler);

            output(Environment.NewLine + "Exchanging code for tokens...");
            HttpResponseMessage response = await client.PostAsync(tokenEndpoint, content);
            string responseString = await response.Content.ReadAsStringAsync();
            output(responseString);

            if (!response.IsSuccessStatusCode)
            {
                output("Authorization code exchange failed.");
                return;
            }

            // Sets the Authentication header of our HTTP client using the acquired access token.
            JsonObject tokens = JsonObject.Parse(responseString);
            string accessToken = tokens.GetNamedString("access_token");
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);

            // Makes a call to the Userinfo endpoint, and prints the results.
            output("Making API Call to Userinfo...");
            HttpResponseMessage userinfoResponse = client.GetAsync(userInfoEndpoint).Result;
            string userinfoResponseContent = await userinfoResponse.Content.ReadAsStringAsync();
            output(userinfoResponseContent);
        }</pre>
<p>As you can see at the end of that sample, we use the resulting access_token as a Bearer token to finally request the user information. Because there isn’t any helper libraries or SDK to wrap access to Google services, we have to do it ourselves once again via a simple HTTP REST call to the user endpoint which is defined in the app:</p>
<pre class="crayon-plain-tag">const string userInfoEndpoint = "https://www.googleapis.com/oauth2/v3/userinfo";</pre>
<p>In the end, the result is the same, and we can now review the user’s profile information just like before, which the app outputs as text:</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-Sample-Result.png" rel="prettyPhoto[gallery-ELm7]"><img class="alignnone size-medium wp-image-6219" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-Sample-Result-300x232.png" alt="Google-Cloud-Platform-UWP-Sample-Result" width="300" height="232" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-Sample-Result-300x232.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-Sample-Result-768x593.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-Sample-Result-1024x791.png 1024w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Although this works just fine, the authentication process demonstrated by the sample is obviously a bit cumbersome. Launching the browser and leaving the app is not an ideal experience for the user.</p>
<p>Fortunately, we can fix that by leveraging a helpful class from the .NET framework.</p>
<h2>WebAuthenticationBroker</h2>
<p>The <a href="https://msdn.microsoft.com/en-us/library/windows/apps/windows.security.authentication.web.webauthenticationbroker.aspx">WebAuthenticationBroker</a> class exposes the static method <a href="https://msdn.microsoft.com/en-us/library/windows/apps/br212068.aspx">AuthenticateAsync</a> that accepts the same authorization URL that previously was launched by the browser. The difference here is that instead of leaving the app to authorize, it pops up an embedded browser so that you can complete the authorization from within the app itself.</p>
<p>A more complete description of this process is in the MSDN docs: <a href="https://msdn.microsoft.com/windows/uwp/security/web-authentication-broker">Web authentication broker</a></p>
<p>For this to work, however, we do have to pass a URI that makes sense for the identity provider to redirect back to the app such that the broker can continue the process and hand the result back to the app.</p>
<p>While I began putting this together, I actually discovered that another developer <a href="https://github.com/LorenzCK">LorenzCK</a> has already created such an update, and has created a <a href="https://github.com/googlesamples/oauth-apps-for-windows/pull/1/commits/9cf706ae94e539892753035212d8db1592451206">pull request</a> to the Google sample that updates the sample to use this broker. Many thanks to the developer for sharing this code!</p>
<p>Replacing the MainPage.xaml.cs of the current sample with the <a href="https://raw.githubusercontent.com/LorenzCK/oauth-apps-for-windows/9cf706ae94e539892753035212d8db1592451206/OAuthUniversalApp/OAuthUniversalApp/MainPage.xaml.cs">updated code</a> simplifies things quite a bit. Because we no longer leave the app to authenticate the user, we don’t need to save any of the generated values to local storage, and can handle the entire operation via the async authorize method of the broker.</p>
<pre class="crayon-plain-tag">private async void button_Click(object sender, RoutedEventArgs e)
        {
            // Generates state and PKCE values.
            string state = randomDataBase64url(32);
            string code_verifier = randomDataBase64url(32);
            string code_challenge = base64urlencodeNoPadding(sha256(code_verifier));
            const string code_challenge_method = "S256";

            // Creates the OAuth 2.0 authorization request.
            string authorizationRequest = string.Format("{0}?response_type=code&amp;scope=openid%20profile&amp;redirect_uri={1}&amp;client_id={2}&amp;state={3}&amp;code_challenge={4}&amp;code_challenge_method={5}",
                authorizationEndpoint,
                System.Uri.EscapeDataString(redirectURI),
                clientID,
                state,
                code_challenge,
                code_challenge_method);

            output("Opening authorization request URI: " + authorizationRequest);

            var result = await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.UseTitle, new Uri(authorizationRequest), new Uri(authorizationCompleteEndPoint));
            output("WebAuthenticationBroker result: " + result.ResponseStatus);
            switch (result.ResponseStatus)
            {
                case WebAuthenticationStatus.Success:
                    string data = result.ResponseData;
                    // Strip authentication result from data and process rest of encoded data.
                    ProcessAuthorization(data.Substring(data.IndexOf(' ') + 1), state, code_verifier);
                    break;

                case WebAuthenticationStatus.ErrorHttp:
                    output("HTTP error: " + result.ResponseErrorDetail);
                    break;

                case WebAuthenticationStatus.UserCancel:
                    break;
            }
        }</pre>
<p>Once a successful result is returned from the operation, we can parse the result, validate like we did before, and exchange the code for an access token:</p>
<pre class="crayon-plain-tag">/// &lt;summary&gt;
        /// Processes the OAuth 2.0 Authorization Response
        /// &lt;/summary&gt;
        /// &lt;param name="data"&gt;Incoming data formatted as a query string&lt;/param&gt;
        /// &lt;param name="expected_state"&gt;Expected state value to verify that this app has initiated authentication&lt;/param&gt;
        private void ProcessAuthorization(string data, string expected_state, string code_verifier)
        {
            output("MainPage received authorizationResponse: " + data);

            // Parses URI params into a dictionary
            // ref: http://stackoverflow.com/a/11957114/72176
            Dictionary&lt;string, string&gt; queryStringParams = data.Split('&amp;').ToDictionary(
                c =&gt; c.Split('=')[0],
                c =&gt; Uri.UnescapeDataString(c.Split('=')[1])
            );

            if (queryStringParams.ContainsKey("error"))
            {
                output(String.Format("OAuth authorization error: {0}.", queryStringParams["error"]));
                return;
            }

            if (!queryStringParams.ContainsKey("code")
                || !queryStringParams.ContainsKey("state"))
            {
                output("Malformed authorization response. " + data);
                return;
            }

            // Gets the Authorization code &amp; state
            string code = queryStringParams["code"];
            string incoming_state = queryStringParams["state"];

            // Compares the received state to the expected value, to ensure that
            // this app made the request which resulted in authorization
            if (incoming_state != expected_state)
            {
                output(String.Format("Received request with invalid state ({0})", incoming_state));
                return;
            }

            // Authorization Code is now ready to use!
            output(Environment.NewLine + "Authorization code: " + code);

            performCodeExchangeAsync(code, code_verifier);
        }</pre>
<p>In addition, we no longer have to use the protocol activation, since we never leave the app, so this setting can be removed from the manifest as well. Instead, the return uri uses this format:</p>
<pre class="crayon-plain-tag">const string redirectURI = "urn:ietf:wg:oauth:2.0:oob:auto";</pre>
<p>This tells Google to return the result to the title bar of the browser (in this case, the WebAuthenticationBroker). More information on the different options for redirect URI is here: https://developers.google.com/api-client-library/python/auth/installed-app#choosingredirecturi</p>
<p>Now when we run the app and click the button to login, the web broker launches inside the app, where we can safely provide our Google credentials and authorize it:</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-WebAuthenticationBroker.png" rel="prettyPhoto[gallery-ELm7]"><img class="alignnone size-medium wp-image-6220" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-WebAuthenticationBroker-300x232.png" alt="Google-Cloud-Platform-UWP-WebAuthenticationBroker" width="300" height="232" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-WebAuthenticationBroker-300x232.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-WebAuthenticationBroker-768x593.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-UWP-WebAuthenticationBroker-1024x791.png 1024w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Authorizing the application closes the broker and processes the result just like before, showing the same user profile information in the app, all without ever leaving it!</p>
<h2>Wrapping up and Next Steps</h2>
<p>The Google Windows OAuth Samples are a great way to get started adding Google services to your Windows 10 apps by easily allowing users to authorize access to their accounts. Thanks to the efforts of <a href="https://github.com/LorenzCK">LorenzCK</a> we can take this a step further and leverage the frameworks WebAuthenticationBroker to simplify this process even further, resulting in a better experience for the user.</p>
<p>However, now that we’ve authorized a user account so we can access Google services, we need to be able to take it a step further, authorizing our own app to access our Google Cloud Platform services.</p>
<p>Fortunately, this is also possible, and will the subject of our next post. Until then as always, I hope this was helpful and thanks for reading!</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/using-google-services-in-uwp-c-apps-part-1/">Using Google Services in UWP C# Apps – Part 1</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/using-google-services-in-uwp-c-apps-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6215</post-id>	</item>
		<item>
		<title>Redis Caching in the Google Cloud Platform</title>
		<link>https://blog.falafel.com/redis-caching-in-the-google-cloud-platform/</link>
		<comments>https://blog.falafel.com/redis-caching-in-the-google-cloud-platform/#comments</comments>
		<pubDate>Fri, 03 Feb 2017 14:00:38 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Cloud Platform]]></category>
		<category><![CDATA[GCE]]></category>
		<category><![CDATA[GCP]]></category>
		<category><![CDATA[redis]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6116</guid>
		<description><![CDATA[<p>This is post 15 of 17 in the series &#8220;Google Cloud for the .NET Developer&#8221; Caching is one of those solutions that is often added after you realize that there is a performance problem with your system. For example, fetching records from a database may be fast when you are developing locally as the only user. But, in production with hundreds or thousands of simultaneous requests taking place, that disk-based database will soon become a bottleneck. If the data is slowly changing, then there is really no need to hit the database itself after the first read: simply save the data to...</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/redis-caching-in-the-google-cloud-platform/">Redis Caching in the Google Cloud Platform</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<aside class="wp-post-series-box series-google-cloud-for-the-net-developer">
	<p class="wp-post-series-name">
		This is post 15 of 17 in the series <em>&ldquo;Google Cloud for the .NET Developer&rdquo;</em>	</p>

	
	</aside>
<p>Caching is one of those solutions that is often added after you realize that there is a performance problem with your system. For example, fetching records from a database may be fast when you are developing locally as the only user. But, in production with hundreds or thousands of simultaneous requests taking place, that disk-based database will soon become a bottleneck. If the data is slowly changing, then there is really no need to hit the database itself after the first read: simply save the data to cache after fetching it, and read it out of cache instead on subsequent requests.</p>
<p>Redis is a popular open-source highly-scalable shared in-memory data store. You can think of it as a database of key/value pairs, like a NoSQL database, but it can also serve as a message queue and pub/sub server. And, while its normal operating mode is in-memory on one machine, there is also support for clustering and persistence to disk.</p>
<p>Redis is often implemented as part of a solution because it is:</p>
<ul>
<li><strong>Cross-Platform:</strong> Being open source, a Redis server can run on both Windows and Linux operating systems. Even if your solution is based on .NET running on Windows Servers, the Redis server itself can be hosted on a lower-cost Linux instance.</li>
<li><strong>Cross-Server:</strong> Redis can run locally on the same machine as your application, but it is often installed as its own server in order to permit multiple machines to access it. In this way, the same data cache can be shared among servers.</li>
<li><strong>Cross-Application:</strong> A client API within your application is used to access the Redis server. One application can place data into Redis for another application to consume (like a message queue).</li>
<li><strong>Cross-Process:</strong> Even within the same application, Redis can be used as a means to decouple code that runs in different processes.</li>
</ul>
<h2>Installing Redis in the Google Cloud</h2>
<p>Unlike features such as Cloud SQL (MySQL) or Cloud BigTable, Redis is not a first-class citizen in the Google Cloud Platform. So, you have to somehow install it as a Compute Engine instance.</p>
<p>One easy way to do this is to use the Cloud Launcher. Search for &#8220;redis&#8221;, and you will find both a Google-provided and a Bitnami-provided image:</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/cloud-launcher-redis-images.png" rel="prettyPhoto[gallery-xDTN]"><img class="alignnone wp-image-6118 size-large" src="https://blog.falafel.com/wp-content/uploads/2017/01/cloud-launcher-redis-images-1024x592.png" alt="Searching for &quot;redis&quot; will result in a Google-provided image and a Bitnami-provided image" width="1024" height="592" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/cloud-launcher-redis-images-1024x592.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/cloud-launcher-redis-images-300x173.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/cloud-launcher-redis-images-768x444.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/cloud-launcher-redis-images.png 1514w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>The Google-curated image is configured as an advanced Redis cluster of 3 x n1-standard-4 instances with a 10GB boot disk running on Debian 8, and costs an estimated $400/month to run. The Bitnami-curated image is very simple out of the box, using a single f1-micro instance with a 10GB disk running on Debian 8, and costs an estimated $5/month.</p>
<p>For those who do not want to administer Redis themselves, another popular option is to use a subscription service to set up and manage Redis for you. <a href="https://redislabs.com/">Redis Labs</a>, for example, provides Redis-as-a-service hosted on a number of popular cloud platforms (GCE included) for a reasonable price. It even includes a free tier that is sufficient for evaluation or even as the caching layer for small applications.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/redis-labs-create-cache-plan.png" rel="prettyPhoto[gallery-xDTN]"><img class="alignnone wp-image-6119 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/redis-labs-create-cache-plan.png" alt="The Redis Labs free cache plan provides a single 30MB database for free" width="950" height="624" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/redis-labs-create-cache-plan.png 950w, https://blog.falafel.com/wp-content/uploads/2017/01/redis-labs-create-cache-plan-300x197.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/redis-labs-create-cache-plan-768x504.png 768w" sizes="(max-width: 950px) 100vw, 950px" /></a></p>
<p>After creating a subscription, you must add the database(s) via the website:</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/redis-labs-create-database.png" rel="prettyPhoto[gallery-xDTN]"><img class="alignnone wp-image-6120 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/redis-labs-create-database.png" alt="Create a database to be used as your system's caching layer" width="953" height="715" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/redis-labs-create-database.png 953w, https://blog.falafel.com/wp-content/uploads/2017/01/redis-labs-create-database-300x225.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/redis-labs-create-database-768x576.png 768w" sizes="(max-width: 953px) 100vw, 953px" /></a></p>
<p>Redis Labs will then take care of the rest, creating your image that you can immediately use from your application.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/redis-labs-manage-resources-1.png" rel="prettyPhoto[gallery-xDTN]"><img class="alignnone wp-image-6122 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/redis-labs-manage-resources-1.png" width="953" height="243" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/redis-labs-manage-resources-1.png 953w, https://blog.falafel.com/wp-content/uploads/2017/01/redis-labs-manage-resources-1-300x76.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/redis-labs-manage-resources-1-768x196.png 768w" sizes="(max-width: 953px) 100vw, 953px" /></a></p>
<p>Once you are up and running, you can also access monitoring and statistics from the Redis Labs website.</p>
<h2>Using Redis for Caching in your .NET Application</h2>
<p>Search NuGet for &#8220;redis&#8221;, and you&#8217;ll find a lot of results. But, one in particular is the <a href="https://github.com/StackExchange/StackExchange.Redis"><strong>StackExchange.Redis</strong></a> client library with over 1.4 million downloads. This is a general-purpose Redis client that is built for performance, and supports all of the <a href="https://redis.io/commands">Redis Commands</a>. If you have ever searched for help on StackOverflow, then you have been on the receiving end of StackExchange.Redis in action.</p>
<pre class="crayon-plain-tag">PM&gt; Install-Package StackExchange.Redis</pre>
<p>Let&#8217;s look at how to build our own simple <a href="https://msdn.microsoft.com/en-gb/library/dn589799.aspx?f=255&amp;MSPPError=-2147217396">Cache-Aside</a> implementation using StackEchange.Redis. Cache-Aside is a design pattern that tries to read data from cache first. If the data is not there, then it will fetch the data from the database and save it to cache for subsequent reads.</p>
<p><em>Note: This sample is a complete Console application, but the interesting part of the Cache-Aside implementation is in the highlighted <strong>GetSpeakerById()</strong> method. To run this locally, be sure to install the StackExchange.Redis and Newtonsoft.Json NuGet packages, as well as substitute your own Redis server information.</em></p>
<pre class="crayon-plain-tag">using System;
using System.Threading.Tasks;
using StackExchange.Redis;

namespace dotnet_sample
{
    class Program
    {
        static void Main(string[] args)
        {
            var example = new Example();

            do
            {
                Console.Write("ID &gt; ");
                var input = Console.ReadLine();

                if (input != "")
                {
                    int id = -1;
                    int.TryParse(input, out id);

                    var task = example.GetSpeakerById(id);
                    Task.WaitAll(task);

                    var speaker = task.Result;

                    Console.WriteLine("{0}: Timestamp = {1}", speaker.ID, speaker.TimeStamp);
                }
                else
                {
                    break;
                }
            }
            while (true);
        }

        class Example
        {
            private readonly ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("pub-redis-11750...com:11750,password=12345");

            public async Task&lt;Speaker&gt; GetSpeakerById(int id)
            {
                Speaker speaker = null;
                var key = $"speaker:{id}";

                var db = redis.GetDatabase();
                string data = await db.StringGetAsync(key);

                if (data != null)
                {
                    speaker = Newtonsoft.Json.JsonConvert.DeserializeObject&lt;Speaker&gt;(data);
                }

                if (speaker == null)
                {
                    speaker = await GetSpeakerByIdFromDb(id);

                    if (speaker != null)
                    {
                        data = Newtonsoft.Json.JsonConvert.SerializeObject(speaker);
                        await db.StringSetAsync(key, data, TimeSpan.FromSeconds(30));
                    }
                }

                return speaker;
            }

            private async Task&lt;Speaker&gt; GetSpeakerByIdFromDb(int id)
            {
                // Implement database call to retrieve speaker object...

                return new Speaker
                {
                    ID = id,
                    Name = "Jason Follas",
                    Bio = "Jason Follas is a Sr. Architect for Falafel Software and lives near Toledo, OH...",
                    Twitter = "@jfollas",
                    ImageUrl = "https://s.gravatar.com/avatar/f89789e4c3445d06ff7b5d97489d902d?s=80",
                    TimeStamp = DateTime.Now
                };
            }

        }

        class Speaker
        {
            public int ID { get; set; }
            public string Name { get; set; }
            public string Bio { get; set; }
            public string Twitter { get; set; }
            public string ImageUrl { get; set; }
            public DateTime TimeStamp { get; set; }
        }
    }
}</pre>
<p>Some things to note in this code:</p>
<ul>
<li>The <strong>ConnectionMultiplexer</strong> is a long-lived object. Create it once and just keep it around for the life of your application.</li>
<li>The method names are slightly different than the actual <a href="https://redis.io/commands">Redis commands</a>. For example, Redis&#8217;s <strong>GET</strong> is called <strong>StringGet</strong> in this library.</li>
<li>The library provides both synchronous and asynchronous versions of each command. For example: <strong>StringGet()</strong> and <strong>await StringGetAsync()</strong></li>
<li>Since Redis stores values as strings, the object graph is serialized to and from JSON in this code using the <strong>Newtonsoft.Json</strong> library.</li>
</ul>
<p>The example app above sets the cache timeout to 30 seconds when the object is written to cache. After 30 seconds, the object is considered stale and will be removed. We can observe that the cached object is being used by watching the timestamp. Whenever it changes for a given ID, then we know that a &#8220;database fetch&#8221; has occurred:</p>
<pre class="crayon-plain-tag">ID &gt; 1
1: Timestamp = 1/16/2017 4:57:48 PM

ID &gt; 2
2: Timestamp = 1/16/2017 4:57:51 PM

ID &gt; 1
1: Timestamp = 1/16/2017 4:57:48 PM

ID &gt; 1
1: Timestamp = 1/16/2017 4:58:38 PM

ID &gt;</pre>
<p>You will need to decide what expiration is appropriate for your own application and data. Also, if an object is updated, it is common to remove it from cache at the same time as committing the changes to the database so that a fresh read is used on the next request.</p>
<h2>Specialized Libraries</h2>
<p>While the StackExchange.Redis library is a complete Redis client, using it directly might require more coding than you were hoping for. Fortunately, Redis is a very popular platform, and a number of specialized libraries have been written that use it as their backend for caching, session storage, message queueing, and a host of other things. In a lot of cases, these libraries actually use the StackExchange.Redis client themselves.</p>
<p>Here is a sampling of libraries and frameworks that can use Redis:</p>
<p><a href="http://hangfire.io/">Hangfire.io</a>: An easy way to perform background processing in .NET and .NET Core applications. No Windows Service or separate process required.</p>
<p><a href="http://www.cachemanager.net/">CacheManager</a>: CacheManager is an open source caching framework for .NET written in C# and is available via NuGet. It supports various cache providers and implements many advanced features</p>
<p><a href="https://github.com/thepirat000/CachingFramework.Redis">CachingFramework.Redis</a>: Distributed caching based on StackExchange.Redis and Redis. Includes support for tagging and is cluster-compatible.</p>
<p><a href="https://github.com/TheCloudlessSky/Harbour.RedisSessionStateStore">Harbour.RedisSessionStateStore</a>: Redis based SessionStateStoreProvider written in C# using ServiceStack.Redis</p>
<p><a href="https://github.com/silentbobbert/EFCache.Redis">EFCache.Redis</a>: Extends <a href="https://github.com/moozzyk/EFCache">EFCache</a> by adding Redis support</p>
<p><a href="https://github.com/jmenziessmith/TagCache.Redis">TagCache.Redis</a>: .NET Redis Cache with support for tagging</p>
<p><a href="https://github.com/welegan/RedisSessionProvider">RedisSessionProvider</a>: Provides a drop-in class library that makes ASP.NET&#8217;s System.Web Session object store its contents in a Redis server or servers.</p>
<p><a href="https://servicestack.net/">ServiceStack</a>: Thoughtfully architected, obscenely fast, thoroughly enjoyable web services for all. <em>Note: Commercial product, developer licensing required</em></p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/redis-caching-in-the-google-cloud-platform/">Redis Caching in the Google Cloud Platform</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/redis-caching-in-the-google-cloud-platform/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6116</post-id>	</item>
		<item>
		<title>Entity Framework with Google Cloud SQL</title>
		<link>https://blog.falafel.com/entity-framework-with-google-cloud-sql/</link>
		<comments>https://blog.falafel.com/entity-framework-with-google-cloud-sql/#comments</comments>
		<pubDate>Thu, 02 Feb 2017 14:00:31 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Cloud Platform]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[Cloud SQL]]></category>
		<category><![CDATA[Entity Framework]]></category>
		<category><![CDATA[Google Cloud for the .NET Developer]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6093</guid>
		<description><![CDATA[<p>In a previous example, I showed how to create and connect to a Cloud SQL instance database using Visual Studio's Server Explorer. But there's more to that story! I also want to show how to take that connection and use our Cloud SQL database with Entity Framework in a sample Web application.</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/entity-framework-with-google-cloud-sql/">Entity Framework with Google Cloud SQL</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<aside class="wp-post-series-box series-google-cloud-for-the-net-developer">
	<p class="wp-post-series-name">
		This is post 14 of 17 in the series <em>&ldquo;Google Cloud for the .NET Developer&rdquo;</em>	</p>

	
	</aside>
<p>If you are a .NET developer and have been following this series, you may have read the previous section covering Google Cloud Platform&#8217;s <a href="https://blog.falafel.com/cloud-storage-options-part-1/ ‎" target="_blank">Cloud SQL as part of the Cloud Storage Options.</a> In that example, I showed how to create and connect to a Cloud SQL instance database using Visual Studio&#8217;s Server Explorer. But there&#8217;s more to that story! I also want to show how to take that connection and use our Cloud SQL database with Entity Framework in a sample Web application.</p>
<p>Before we create the Entity Framework model, we should add some tables to test with. At this point you can use ANY interface you like to execute the following commands, but my favorite ad-hoc query execution environment is <a href="https://www.linqpad.net/" target="_blank">LINQPad</a>! It&#8217;s free and I wanted to see how it works with a Cloud SQL instance. Just for the sake of completeness, I&#8217;ll show you how to connect LINQPad to the Cloud SQL instance.</p>
<h3>First Steps</h3>
<p>Before you start, <a href="https://blog.falafel.com/cloud-storage-options-part-1/ ‎" target="_blank">review the previous post</a> and create your Cloud SQL instance, either using your gcloud shell or the GCP Console.</p>
<h3>LINQPad Connection</h3>
<p>Before you can connect to LINQPad, you&#8217;ll have to add a MySQL driver. If you don&#8217;t see a driver in the list that supports MySQL, you can use the &#8220;View more drivers&#8221; option to install the IQ driver.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/EFlinqpad.png" rel="prettyPhoto[gallery-UF6S]"><img class="alignnone wp-image-6198 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/EFlinqpad.png" width="677" height="472" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/EFlinqpad.png 677w, https://blog.falafel.com/wp-content/uploads/2017/01/EFlinqpad-300x209.png 300w" sizes="(max-width: 677px) 100vw, 677px" /></a></p>
<p>Then, create the connection using the IP address of your Cloud SQL instance and the root user password.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/EFlinqpad2.png" rel="prettyPhoto[gallery-UF6S]"><img class="alignnone wp-image-6199 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/EFlinqpad2.png" width="376" height="390" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/EFlinqpad2.png 376w, https://blog.falafel.com/wp-content/uploads/2017/01/EFlinqpad2-289x300.png 289w" sizes="(max-width: 376px) 100vw, 376px" /></a></p>
<p>Once the connection succeeds, you can create a Query. Among the reasons I love LINQpad is the ability to write queries in C#, but in this case you can choose SQL for the language.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/EFlinqpad3.png" rel="prettyPhoto[gallery-UF6S]"><img class="alignnone wp-image-6200 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/EFlinqpad3.png" width="408" height="140" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/EFlinqpad3.png 408w, https://blog.falafel.com/wp-content/uploads/2017/01/EFlinqpad3-300x103.png 300w" sizes="(max-width: 408px) 100vw, 408px" /></a></p>
<p>Now execute the following SQL to create a table of survey questions, with a foreign key to a table of question types.</p>
<pre class="crayon-plain-tag">CREATE TABLE IF NOT EXISTS questiontype (
  questiontypeID  int unsigned  NOT NULL AUTO_INCREMENT,
  name  varchar(30)  NOT NULL DEFAULT '',
  PRIMARY KEY (`questiontypeID`)
);

CREATE TABLE IF NOT EXISTS surveyquestion (
  surveyquestionID    int unsigned  NOT NULL AUTO_INCREMENT,
  surveyquestiontext         varchar(255)       NOT NULL DEFAULT '',
  questiontypeID    int unsigned  NOT NULL,
  PRIMARY KEY (surveyquestionID),
  FOREIGN KEY (questiontypeID) REFERENCES questiontype (questiontypeID)
);

INSERT INTO questiontype (name) VALUES
 ('yesno'),
 ('starrating'),
 ('shortanswer')
;

INSERT INTO surveyquestion (surveyquestiontext, questiontypeID) VALUES
  ('Would you purchase this product again?', 1),
  ('How would you rate the quality of our product?', 2),
  ('How would you rate the price of our product?', 2),
  ('Do you have any comments to add?', 3)
;</pre>
<p>You should now be able to expand the Tables view in LINQpad and see our sample schema.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/EFlinqpad4.png" rel="prettyPhoto[gallery-UF6S]"><img class="alignnone wp-image-6203 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/EFlinqpad4.png" width="377" height="291" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/EFlinqpad4.png 377w, https://blog.falafel.com/wp-content/uploads/2017/01/EFlinqpad4-300x232.png 300w" sizes="(max-width: 377px) 100vw, 377px" /></a></p>
<h3>Add an Entity Framework model</h3>
<p>To demonstrate an Entity Framework model created from this Cloud SQL database, we can use an empty WebAPI web application project, <a href="https://github.com/rhagerman/fscloudsqlentityframework" target="_blank">which you can download here</a>.</p>
<p>Note: you&#8217;ll need to add some MySQL nuget packages if you are creating this project on your own.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/ef6.png" rel="prettyPhoto[gallery-UF6S]"><img class="alignnone wp-image-6193" src="https://blog.falafel.com/wp-content/uploads/2017/01/ef6.png" width="746" height="423" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/ef6.png 868w, https://blog.falafel.com/wp-content/uploads/2017/01/ef6-300x170.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/ef6-768x435.png 768w" sizes="(max-width: 746px) 100vw, 746px" /></a></p>
<p>Creating the model is very straightforward. Start by adding the ADO.NET model object using the wizard.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/ef3.png" rel="prettyPhoto[gallery-UF6S]"><img class="alignnone wp-image-6201 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/ef3.png" width="659" height="440" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/ef3.png 659w, https://blog.falafel.com/wp-content/uploads/2017/01/ef3-300x200.png 300w" sizes="(max-width: 659px) 100vw, 659px" /></a></p>
<p>And if you have the packages above, you will be able to create the EF Designer model and connect to the Cloud SQL instance just as we did before.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/ef4.png" rel="prettyPhoto[gallery-UF6S]"><img class="alignnone wp-image-6202 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/ef4.png" width="606" height="544" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/ef4.png 606w, https://blog.falafel.com/wp-content/uploads/2017/01/ef4-300x269.png 300w" sizes="(max-width: 606px) 100vw, 606px" /></a></p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/ef5.png" rel="prettyPhoto[gallery-UF6S]"><img class="alignnone wp-image-6192 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/ef5.png" width="607" height="546" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/ef5.png 607w, https://blog.falafel.com/wp-content/uploads/2017/01/ef5-300x270.png 300w" sizes="(max-width: 607px) 100vw, 607px" /></a></p>
<p>Save the connection and choose to add our tables to the model.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/ef7.png" rel="prettyPhoto[gallery-UF6S]"><img class="alignnone wp-image-6194 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/ef7.png" width="618" height="556" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/ef7.png 618w, https://blog.falafel.com/wp-content/uploads/2017/01/ef7-300x270.png 300w" sizes="(max-width: 618px) 100vw, 618px" /></a></p>
<p>Now we can see our tables in the model, and see that a navigation property has been added to let us navigate from questions to question types.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/ef8.png" rel="prettyPhoto[gallery-UF6S]"><img class="alignnone wp-image-6195 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/ef8.png" width="466" height="298" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/ef8.png 466w, https://blog.falafel.com/wp-content/uploads/2017/01/ef8-300x192.png 300w" sizes="(max-width: 466px) 100vw, 466px" /></a></p>
<p>Great! At this point be sure to build the application. Next, let&#8217;s use that model in a very simple test API call.</p>
<p>Add a controller called SurveyQuestionsController.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/ef10.png" rel="prettyPhoto[gallery-UF6S]"><img class="alignnone wp-image-6204 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/ef10.png" width="336" height="236" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/ef10.png 336w, https://blog.falafel.com/wp-content/uploads/2017/01/ef10-300x211.png 300w" sizes="(max-width: 336px) 100vw, 336px" /></a></p>
<p>And in the controller Get method, add the following code which uses the new Entity Framework model classes.</p>
<pre class="crayon-plain-tag">public class SurveyQuestionsController : ApiController
    {
        // GET api/&lt;controller&gt;
        public HttpResponseMessage Get()
        {
            using (var db = new falafelefdemoEntities())
            {
              var questions = db.surveyquestions.Select(q =&gt;
                   new
                   {
                       Text = q.surveyquestiontext,
                       TypeName = q.questiontype.name
                   }).ToList();
                return Request.CreateResponse(HttpStatusCode.OK, questions);
            }
        }

    }</pre>
<p>If you run the application now, you can test this API call by browsing (<a href="https://www.getpostman.com/" target="_blank">or using Postman</a>, if you prefer) to the host address + /api/surveyquestions. The response should include the questions plus the names of their question types, which was assembled using our Entity Framework navigation property.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/ef11.png" rel="prettyPhoto[gallery-UF6S]"><img class="alignnone wp-image-6197 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/ef11.png" width="735" height="256" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/ef11.png 735w, https://blog.falafel.com/wp-content/uploads/2017/01/ef11-300x104.png 300w" sizes="(max-width: 735px) 100vw, 735px" /></a></p>
<p>And there you have it! A working Entity Framework model, from Visual Studio, all using Google Cloud Platform&#8217;s Cloud SQL instance.</p>
<div>
<h3>Other Resources</h3>
</div>
<div>
<div><a href="https://cloud.google.com/sql/docs/" target="_blank">More on Cloud SQL</a></div>
<div><a href="https://www.asp.net/entity-framework" target="_blank">More on Entity Framework</a></div>
<div><a href="https://developers.google.com/gdata/client-cs" target="_blank">.NET Client Library Developer&#8217;s Guide</a></div>
</div>
<div>
<div><a href="https://github.com/GoogleCloudPlatform/dotnet-docs-samples/tree/quickstarts" target="_blank">Google Cloud .NET Code Sample Quickstarts</a></div>
</div>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/entity-framework-with-google-cloud-sql/">Entity Framework with Google Cloud SQL</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/entity-framework-with-google-cloud-sql/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6093</post-id>	</item>
		<item>
		<title>Cloud Storage Options Part 2</title>
		<link>https://blog.falafel.com/cloud-storage-options-part-2/</link>
		<comments>https://blog.falafel.com/cloud-storage-options-part-2/#comments</comments>
		<pubDate>Wed, 01 Feb 2017 14:00:26 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Cloud Platform]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Cloud Development]]></category>
		<category><![CDATA[Cloud Storage]]></category>
		<category><![CDATA[GCP]]></category>
		<category><![CDATA[Google Cloud for the .NET Developer]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6092</guid>
		<description><![CDATA[<p>This is a continuation of Cloud Storage Options Part 1, which covers Google Cloud Storage and Google Cloud SQL, both from a .NET developer's perspective. Part 2 includes the two remaining structured storage solutions offered in GCP: Cloud Datastore and Cloud BigTable, and again focuses on how .NET developers can get started leveraging these storage options for themselves.</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/cloud-storage-options-part-2/">Cloud Storage Options Part 2</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<aside class="wp-post-series-box series-google-cloud-for-the-net-developer">
	<p class="wp-post-series-name">
		This is post 13 of 17 in the series <em>&ldquo;Google Cloud for the .NET Developer&rdquo;</em>	</p>

	
	</aside>
<div>This is a continuation of <a href="https://blog.falafel.com/cloud-storage-options-part-1/" target="_blank">Cloud Storage Options Part 1</a>, which covers Google Cloud Storage and Google Cloud SQL, both from a .NET developer&#8217;s perspective. Part 2 includes the two remaining structured storage solutions offered in GCP: Cloud Datastore and Cloud BigTable, and again focuses on how .NET developers can get started leveraging these storage options for themselves.</div>
<h3>NoSQL</h3>
<div>Although Google categorizes them as &#8220;structured&#8221;, Datastore and BigTable aren&#8217;t as structured as you might be used to if you come from a background of relational databases, like MS SQL Server. These two Cloud Storage options are both NoSQL storage solutions. What is<a href="http://nosql-database.org/" target="_blank"> NoSQL</a>? In part, it is a storage solution resulting from the internet-age&#8217;s exponential data growth for both user and device data. That data growth resulted in the need for a new kind of storage solution &#8211; one that could be fast, easily distributed, and flexible. As the name implies, NoSQL (Not Only SQL) storage options are non-relational, which gives them an advantage if data needs to be flexible, scalable, and lightning fast. Since Google itself started the NoSQL movement <a href="https://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=1&amp;cad=rja&amp;uact=8&amp;ved=0ahUKEwi9vvmBn8fRAhWmwlQKHdJLAlMQFggcMAA&amp;url=http%3A%2F%2Fresearch.google.com%2Farchive%2Fbigtable-osdi06.pdf&amp;usg=AFQjCNHWt7UiCw7feq5ygj2Y5pWeQLPZ9Q&amp;sig2=w9XglslKki0xHOKYIEL6hA" target="_blank">with the original BigTable in 2006</a>, it makes sense that GCP is leading the way today for NoSQL cloud-based solutions.</div>
<h3>Cloud Datastore</h3>
<div><a href="https://cloud.google.com/datastore/" target="_blank">Cloud Datastore</a> is originally the backing technology behind <a href="https://cloud.google.com/appengine/" target="_blank">App Engine</a>, but now is accessible as its own service as well. Google encourages the use of Datastore for flexible, high availability data storage needs that are less than 1TB, after which your storage needs might better be served by Bigtable. In fact, scalability is one of the big pluses for Cloud Datastore. So especially if your data is going to start small and then grow huge, and you need high availability, Datastore is the storage solution Google recommends.</div>
<div></div>
<div>Like <a href="https://azure.microsoft.com/en-us/services/documentdb/" target="_blank">Azure&#8217;s DocumentDB</a>, Cloud Datastore is a document-store NoSQL model. That means it is more than just keys with values, but instead keys with documents. Document in this case just means an object with an internal structure, such as a JSON object. Think of it as semi-structured application data, but also can include hierarchies. User profiles or product catalogs are great examples of data that is well-suited to Cloud Datastore. With Datastore, you often hear about the flexibility of storage, or ad-hoc storage capabilities, but what does that mean? Well, consider that even after storing hundreds objects with the same 3 properties, you can then store the next hundred with those 3 properties plus 3 more. Get the idea?</div>
<div></div>
<div>Oh, did I mention it&#8217;s free to get started with Cloud Datastore? Up to 1GB storage per day, which is enough to get started to see if it is the storage solution for your application. <a href="https://cloud.google.com/datastore/docs/pricing" target="_blank">Storage costs after that</a> are dependent on the amount of data, and also the structure of the data, so you&#8217;ll want to take a look at the <a href="https://cloud.google.com/datastore/docs/concepts/storage-size" target="_blank">size calculations and pricing</a>.</div>
<h3>.NET Datastore API</h3>
<div>For .NET developers, you can get started right away with <a href="https://cloud.google.com/datastore/docs/reference/libraries" target="_blank">the .NET API for Cloud Datastore</a>. Using the library is straightforward in C#, once you get used to the basics. For anyone familiar with relational database structures, here&#8217;s a <a href="https://cloud.google.com/datastore/docs/concepts/overview#comparison_with_traditional_databases" target="_blank">friendly mapping from the documentation to help with the terminology</a>.</div>
<div></div>
<div>
<table>
<thead>
<tr>
<th>Concept</th>
<th>Cloud Datastore</th>
<th>Relational database</th>
</tr>
</thead>
<tbody>
<tr>
<td>Category of object</td>
<td>Kind</td>
<td>Table</td>
</tr>
<tr>
<td>One object</td>
<td>Entity</td>
<td>Row</td>
</tr>
<tr>
<td>Individual data for an object</td>
<td>Property</td>
<td>Field</td>
</tr>
<tr>
<td>Unique ID for an object</td>
<td>Key</td>
<td>Primary key</td>
</tr>
</tbody>
</table>
</div>
<div></div>
<div>Remember, Cloud Datastore Entities of the same Kind can have different Properties. That flexibility comes at a cost, however. Even though Cloud Datastore allows for some SQL-like queries, the functionality is limited. There is no support for join operations, inequality filtering on more than one property, or filtering based on the results of a subquery, just to name a few.</div>
<h3>Using the Console</h3>
<div>To explore Cloud Datastore using the GCP Console, you can select Datastore under Storage, and choose Create an Entity. This is an interesting exercise to demonstrate just how the Entities work, and what working with them in code will entail. First, choose your region and let Google Cloud initialize the Datastore.</div>
<div><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Datastore1.png" rel="prettyPhoto[gallery-cyxP]"><img class="alignnone wp-image-6129" src="https://blog.falafel.com/wp-content/uploads/2017/01/Datastore1.png" width="619" height="248" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Datastore1.png 811w, https://blog.falafel.com/wp-content/uploads/2017/01/Datastore1-300x120.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/Datastore1-768x308.png 768w" sizes="(max-width: 619px) 100vw, 619px" /></a></div>
<div>Now you can set the properties for your Entity. Namespace is important if you plan on having <a href="https://cloud.google.com/datastore/docs/concepts/multitenancy" target="_blank">multitenancy</a>.</div>
<div> <a href="https://blog.falafel.com/wp-content/uploads/2017/01/Datastore2.png" rel="prettyPhoto[gallery-cyxP]"><img class="alignnone wp-image-6130" src="https://blog.falafel.com/wp-content/uploads/2017/01/Datastore2.png" width="457" height="450" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Datastore2.png 483w, https://blog.falafel.com/wp-content/uploads/2017/01/Datastore2-300x296.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/Datastore2-50x50.png 50w" sizes="(max-width: 457px) 100vw, 457px" /></a></div>
<div>Also note the Parent option here &#8211; the description provided is helpful in understanding how data hierarchies work, which is a big part of the appeal of document-store NoSQL.</div>
<div></div>
<div>Now we can start adding properties! The typical options for property type are available, and you can choose whether to index them or not.</div>
<div><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Datastore3.png" rel="prettyPhoto[gallery-cyxP]"><img class="alignnone wp-image-6131" src="https://blog.falafel.com/wp-content/uploads/2017/01/Datastore3.png" width="579" height="383" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Datastore3.png 739w, https://blog.falafel.com/wp-content/uploads/2017/01/Datastore3-300x199.png 300w" sizes="(max-width: 579px) 100vw, 579px" /></a></div>
<div>Interesting to note here are the <a href="https://cloud.google.com/datastore/docs/concepts/entities#array" target="_blank">Array</a> and Embedded Entity types. If you choose these types, you will be presented with pre-formatted JSON in the Value window, which you can alter for your needs.</div>
<div> <a href="https://blog.falafel.com/wp-content/uploads/2017/01/Datastore4.png" rel="prettyPhoto[gallery-cyxP]"><img class="alignnone wp-image-6132" src="https://blog.falafel.com/wp-content/uploads/2017/01/Datastore4.png" width="620" height="276" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Datastore4.png 743w, https://blog.falafel.com/wp-content/uploads/2017/01/Datastore4-300x134.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a></div>
<div>After creating a couple of entities, you can try out querying your Datastore, either by Kind or by <a href="https://cloud.google.com/datastore/docs/reference/gql_reference?" target="_blank">GQL</a>, using the properties you set as indexes. This is a great little test service to play with, because if you&#8217;re used to TSQL, you&#8217;ll almost certainly find some query functionality to be missing. You can take a look at the <a href="https://cloud.google.com/datastore/docs/reference/gql_reference?hl=en_US&amp;_ga=1.199029286.845764359.1483634390#unsupported_features_and_behavior_differences_from_mysqlpython_gql" target="_blank">unsupported features list</a>, if you are unsure why a particular query isn&#8217;t working.</div>
<div> <a href="https://blog.falafel.com/wp-content/uploads/2017/01/Datastore5.png" rel="prettyPhoto[gallery-cyxP]"><img class="alignnone wp-image-6133" src="https://blog.falafel.com/wp-content/uploads/2017/01/Datastore5.png" width="423" height="369" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Datastore5.png 505w, https://blog.falafel.com/wp-content/uploads/2017/01/Datastore5-300x262.png 300w" sizes="(max-width: 423px) 100vw, 423px" /></a></div>
<h3>Example in C#</h3>
<div>So what does a data operation for Cloud Datastore look like in C#? Let&#8217;s take a look. The Cloud Storage C# example code for this series is <a href="https://github.com/FalafelSoftwareInc/GoogleCloudStorageUsingCSharp" target="_blank">available here</a>. Remember, you&#8217;ll need to have set up default application authentication just as in the <a href="https://blog.falafel.com/cloud-storage-options-part-1/" target="_blank">previous post</a>, along with the rest of the setup in the First Steps of the previous examples.</div>
<div></div>
<div>Let&#8217;s start with adding a few entities.</div>
<div>
<pre class="crayon-plain-tag">// dsdb = DatastoreDb.Create(projectId, dsNamespace);
var kFactory = dsdb.CreateKeyFactory("SurveyQuestion");
var entities = new List&lt;Entity&gt;()
{
    new Entity()
    {
        Key = kFactory.CreateIncompleteKey(),
        ["questiontype"] = "yesno",
        ["text"] = "Would you purchase this product again?",
        ["categories"] = new ArrayValue() {Values = {"product", "purchase"}},
    },
    new Entity()
    {
        Key = kFactory.CreateIncompleteKey(),
        ["questiontype"] = "starrating",
        ["text"] = "How would you rate the quality of our product?",
        ["categories"] = new ArrayValue() {Values = {"product", "quality"}},
    },
    new Entity()
    {
        Key = kFactory.CreateIncompleteKey(),
        ["questiontype"] = "starrating",
        ["text"] = "How would you rate the price of our product?",
        ["categories"] = new ArrayValue() {Values = {"product", "price"}},
    }
};

dsdb.Upsert(entities);</pre>
And then doing a simple query by category.<br />
<pre class="crayon-plain-tag">Query query = new Query("SurveyQuestion")
{
    Filter = Filter.Equal("categories", category)
};

var results = dsdb.RunQuery(query).Entities;</pre>
The example code linked above uses these operations in a C# console app, which you can download to get started.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Datastore6.png" rel="prettyPhoto[gallery-cyxP]"><img class="alignnone wp-image-6134 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/Datastore6.png" width="594" height="90" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Datastore6.png 594w, https://blog.falafel.com/wp-content/uploads/2017/01/Datastore6-300x45.png 300w" sizes="(max-width: 594px) 100vw, 594px" /></a></p>
</div>
<h3>Cloud Bigtable</h3>
<div><a href="https://cloud.google.com/bigtable/" target="_blank">Cloud Bigtable</a> is another NoSQL option, one that is most cost-effective for very, very large data sets starting at 1TB. Bigtable is not a document-store, but instead is a Wide Column Store, also known as Extensible Record Store. This is another reason it is recommended for the largest types of data, such as iOT, financial, or geospatial datasets. BigTable is notable for its low-latency and high-throughput, and also it&#8217;s compatibility with other open-source APIs.</div>
<div></div>
<div>To create a BigTable instance, start from the Storage menu in Console, and create a new instance.</div>
<div><a href="https://blog.falafel.com/wp-content/uploads/2017/01/BigTable1.png" rel="prettyPhoto[gallery-cyxP]"><img class="alignnone wp-image-6126" src="https://blog.falafel.com/wp-content/uploads/2017/01/BigTable1.png" width="539" height="302" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/BigTable1.png 777w, https://blog.falafel.com/wp-content/uploads/2017/01/BigTable1-300x168.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/BigTable1-768x430.png 768w" sizes="(max-width: 539px) 100vw, 539px" /></a></div>
<div>You&#8217;ll essentially be creating a cluster of nodes, so beware if you are working off of a trial account this may eat up some of your trial credits. After creation, you can view the instance in the Console dashboard.</div>
<div><a href="https://blog.falafel.com/wp-content/uploads/2017/01/BigTable2.png" rel="prettyPhoto[gallery-cyxP]"><img class="alignnone wp-image-6127" src="https://blog.falafel.com/wp-content/uploads/2017/01/BigTable2.png" width="368" height="727" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/BigTable2.png 491w, https://blog.falafel.com/wp-content/uploads/2017/01/BigTable2-152x300.png 152w" sizes="(max-width: 368px) 100vw, 368px" /></a></div>
<div></div>
<div>
<h3>Bigtable and HBase</h3>
</div>
<div>Bigtable supports the open-source <a href="http://hbase.apache.org/" target="_blank">HBase API</a>, , making it a natural choice if you are experienced with HBase API and the Hadoop ecosystem. A cloud storage solution unique to Google Cloud Platform alone, Bigtable targets very large datasets in every way. If you aren&#8217;t familiar with this sort of NoSQL storage,<a href="https://cloud.google.com/bigtable/docs/overview#storage-model" target="_blank"> consider a giant table with a sorted key/value map</a> that can scale to billions of rows and thousands of columns, yet can be sparsely populated. Along with the HBase ecosystem for reading, writing, and organizing that data -that&#8217;s Bigtable.</div>
<h3>.NET Compatibility</h3>
<div>BigTable is a little different in that there isn&#8217;t (at the time of this article) a Google-sourced C# API. Instead, you can use the HBase-compliant .NET library of your choice. Google does note (but not explicitly support) <a href="https://cloud.google.com/bigtable/docs/third-party-clients" target="_blank">third-party libraries, one of which is .NET in C#</a>. It is not yet available on Nuget, but can be accessed through the GitHub link. You can also use the HBase Shell for <a href="https://cloud.google.com/bigtable/docs/installing-hbase-shell" target="_blank">Cloud Bigtable</a>.</div>
<div>
<h3>Other Resources</h3>
</div>
<div>
<div><a href="https://www.youtube.com/watch?v=mmjuMyRBPO4" target="_blank">Video Overview of Cloud Storage Options</a></div>
</div>
<div>
<div><a href="https://developers.google.com/gdata/client-cs" target="_blank">.NET Client Library Developer&#8217;s Guide</a></div>
</div>
<div>
<div><a href="https://github.com/GoogleCloudPlatform/dotnet-docs-samples/tree/quickstarts" target="_blank">Google Cloud .NET Code Sample Quickstarts</a></div>
<div><a href="https://cloud.google.com/dotnet/docs/apis" target="_blank">.NET APIs</a></div>
<div><a href="https://cloud.google.com/datastore/docs/datastore-api-tutorial" target="_blank">Datastore API tutorial</a></div>
</div>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/cloud-storage-options-part-2/">Cloud Storage Options Part 2</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/cloud-storage-options-part-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6092</post-id>	</item>
		<item>
		<title>Cloud Storage Options Part 1</title>
		<link>https://blog.falafel.com/cloud-storage-options-part-1/</link>
		<comments>https://blog.falafel.com/cloud-storage-options-part-1/#comments</comments>
		<pubDate>Tue, 31 Jan 2017 14:00:38 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Cloud Platform]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Cloud Development]]></category>
		<category><![CDATA[Cloud Storage]]></category>
		<category><![CDATA[GCP]]></category>
		<category><![CDATA[Google Cloud for the .NET Developer]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6072</guid>
		<description><![CDATA[<p>If you are a .NET developer looking to integrate with Google Cloud, one of the most basic decisions will be what Google Cloud Storage options make sense for you? When you think cloud storage, don't just think blob storage, because Google Cloud Platform storage is really much more diverse than that, from basic blob to fully managed MySQL services to different flavors of NoSQL.</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/cloud-storage-options-part-1/">Cloud Storage Options Part 1</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<aside class="wp-post-series-box series-google-cloud-for-the-net-developer">
	<p class="wp-post-series-name">
		This is post 12 of 17 in the series <em>&ldquo;Google Cloud for the .NET Developer&rdquo;</em>	</p>

	
	</aside>
<div>For any .NET developer looking to integrate with Google Cloud, one of the most basic decisions will be what Google Cloud Storage options make sense for you? When you think cloud storage, don&#8217;t just think blob storage, because Google Cloud Platform storage is really much more diverse than that, from basic blob to fully managed MySQL services to different flavors of NoSQL.</div>
<h3>Storage Options</h3>
<div>If you already have an application on another cloud service provider and are moving to Google Cloud, you likely already know what kind of storage you need and how often you&#8217;ll be accessing it. You&#8217;ll want to start by taking a look at a comparison map and <a href="https://cloud.google.com/storage-options/" target="_blank">finding the equivalent storage options within GCP</a>. Google&#8217;s extensive documentation can make that easier if you are considering migrating <a href="https://cloud.google.com/free-trial/docs/map-azure-google-cloud-platform" target="_blank">from Azure</a> or <a href="https://cloud.google.com/free-trial/docs/map-aws-google-cloud-platform" target="_blank">Amazon</a>, so use those resources to help you decide. You&#8217;ll also want to <a href="https://cloud.google.com/free-trial/docs/estimate-costs-google-cloud-platform" target="_blank">compare pricing, especially if your storage needs are sizable</a>.</div>
<div></div>
<div>But if you are starting from scratch or moving a non-cloud based app to Google Cloud, you have some decisions to make. For me, it&#8217;s always more interesting to start with an example! So let&#8217;s look at how a .NET developer can easily set up and interact with the different offerings of Google Cloud Storage.</div>
<h3>First Steps</h3>
<div>Before you get started, there are a couple of pieces you need to have ready:</div>
<div> a Google Cloud account &#8211; <a href="https://cloud.google.com/free-trial/" target="_blank">just sign up and get 60 days and $300 in credits right away </a></div>
<div> <a href="https://cloud.google.com/storage/docs/projects" target="_blank">a GCP Project already created</a> to house our storage examples</div>
<div> a version of Visual Studio to run a C# sample project. If you don&#8217;t have one, <a href="https://www.visualstudio.com/vs/community/" target="_blank">go grab the Community edition</a></div>
<div><a href="https://cloud.google.com/storage/docs/reference/libraries">the latest Cloud Storage API for .NET</a></div>
<h3>Structured vs Unstructured</h3>
<div>Google Cloud Storage options include both structured and unstructured data. You may be used to just thinking of unstructured blob data as cloud storage, but if you consider all stored information to be &#8220;cloud data&#8221;, then of course structured data can be considered &#8220;Storage&#8221; also. Think of it this way: if you want the data to have rows and/or columns, then it is structured. In parts 1 and 2 of this post, we will take a look at both kinds, starting with unstructured. Then we will look at the 3 main types of structured data storage.</div>
<h3>Google Cloud Storage</h3>
<div>This is unstructured blob storage as you probably already are familiar with. Just as when you create a storage container in Azure, creating a storage container in Google Cloud Storage <a href="https://cloud.google.com/storage/" target="_blank">requires that you select a few options, taking into account the reliability, access frequency, and access speed that you will need</a>. Get used to Google&#8217;s storage terminology &#8211; Buckets are the containers for your Objects, in Google-speak.</div>
<div></div>
<div>First create a Bucket. If you already know the configuration you&#8217;ll need, you will probably prefer to do this using the <a href="https://cloud.google.com/sdk/gcloud/" target="_blank">gCloud command line utility</a>, but for an initial look it is nice to see all of the options using the Console.</div>
<div> <a href="https://blog.falafel.com/wp-content/uploads/2017/01/CloudStorageCreateBucket1.png" rel="prettyPhoto[gallery-VWjZ]"><img class="alignnone wp-image-6077" src="https://blog.falafel.com/wp-content/uploads/2017/01/CloudStorageCreateBucket1.png" width="685" height="351" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/CloudStorageCreateBucket1.png 1669w, https://blog.falafel.com/wp-content/uploads/2017/01/CloudStorageCreateBucket1-300x154.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/CloudStorageCreateBucket1-768x394.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/CloudStorageCreateBucket1-1024x526.png 1024w" sizes="(max-width: 685px) 100vw, 685px" /></a></div>
<div>Start by navigating to Storage in the Console menu, then choose Create Bucket.</div>
<div><a href="https://blog.falafel.com/wp-content/uploads/2017/01/CloudStorageCreateBucket2.png" rel="prettyPhoto[gallery-VWjZ]"><img class="alignnone wp-image-6078" src="https://blog.falafel.com/wp-content/uploads/2017/01/CloudStorageCreateBucket2.png" width="486" height="518" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/CloudStorageCreateBucket2.png 988w, https://blog.falafel.com/wp-content/uploads/2017/01/CloudStorageCreateBucket2-282x300.png 282w, https://blog.falafel.com/wp-content/uploads/2017/01/CloudStorageCreateBucket2-768x818.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/CloudStorageCreateBucket2-962x1024.png 962w" sizes="(max-width: 486px) 100vw, 486px" /></a></div>
<div>To create a multiregional bucket using gcloud use <a href="https://cloud.google.com/storage/docs/gsutil/commands/mb" target="_blank">the mb command</a>:</div>
<div>
<pre class="crayon-plain-tag">gsutil mb -p [yourprojectname] -c multi_regional gs://[youruniquebucketname]</pre>
</div>
<div>Once your bucket is created it is ready to start storing objects, which you can do through the console, even at the folder-level if you use Chrome.</div>
<div><a href="https://blog.falafel.com/wp-content/uploads/2017/01/CloudStorageCreateBucketdemo2.png" rel="prettyPhoto[gallery-VWjZ]"><img class="alignnone wp-image-6080" src="https://blog.falafel.com/wp-content/uploads/2017/01/CloudStorageCreateBucketdemo2.png" width="837" height="180" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/CloudStorageCreateBucketdemo2.png 935w, https://blog.falafel.com/wp-content/uploads/2017/01/CloudStorageCreateBucketdemo2-300x64.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/CloudStorageCreateBucketdemo2-768x165.png 768w" sizes="(max-width: 837px) 100vw, 837px" /></a></div>
<div>Since we are .NET developers, let&#8217;s do an upload using C#!</div>
<h3>Credentials</h3>
<div>First, we need to enable some sort of authentication to our Google Cloud Storage. We aren&#8217;t using any user data, so we will use <a href="https://developers.google.com/identity/protocols/application-default-credentials" target="_blank">Application Default Credentials</a>. And to make things even easier, we can set those up for our development environment with a single gcloud command.</div>
<div>
<pre class="crayon-plain-tag">gcloud beta auth application-default login</pre>
</div>
<div>Note that we are using a beta command, and so you may need to run as an administrator and install the beta commands &#8211; don&#8217;t worry, you will be prompted automatically if that is the case.</div>
<div></div>
<div>The auth command will open a browser window for you to allow authentication, and allow you to use those credentials as a proxy for application credentials for development.</div>
<div></div>
<div><a href="https://blog.falafel.com/wp-content/uploads/2017/01/authenticationsuccess.png" rel="prettyPhoto[gallery-VWjZ]"><img class="alignnone wp-image-6074 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/authenticationsuccess.png" width="1766" height="357" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/authenticationsuccess.png 1766w, https://blog.falafel.com/wp-content/uploads/2017/01/authenticationsuccess-300x61.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/authenticationsuccess-768x155.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/authenticationsuccess-1024x207.png 1024w" sizes="(max-width: 1766px) 100vw, 1766px" /></a></div>
<div>Note: You can access all of the code for this C# example <a href="https://github.com/FalafelSoftwareInc/GoogleCloudStorageUsingCSharp" target="_blank">from the github repository</a>.</div>
<div align="left">
<h3>C# Operations</h3>
<div>Using the .NET storage library, it is very straightforward to create a bucket:</div>
<div>
<pre class="crayon-plain-tag">StorageClient storageClient = StorageClient.Create();
if (storageClient.ListBuckets(projectId).All(b =&gt; b.Name != bucketName))
{
   // Creates the new bucket
   storageClient.CreateBucket(projectId, bucketName);
   Console.WriteLine($"Created new bucket {bucketName}");
   return;
}
Console.WriteLine($"Bucket {bucketName} found");</pre>
And to perform an upload:<br />
<pre class="crayon-plain-tag">StorageClient storageClient = StorageClient.Create();
using (var f = File.OpenRead(filepath))
{
   var objectName = Path.GetFileName(filepath);
   storageClient.UploadObject(bucket, objectName, null, f);
   Console.WriteLine($"{objectName} uploaded to bucket {bucket}");
}</pre>
The github link above will take you to a C# console app that can perform these operations.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/storagebucketdemo.png" rel="prettyPhoto[gallery-VWjZ]"><img class="alignnone wp-image-6090 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/storagebucketdemo.png" width="436" height="162" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/storagebucketdemo.png 436w, https://blog.falafel.com/wp-content/uploads/2017/01/storagebucketdemo-300x111.png 300w" sizes="(max-width: 436px) 100vw, 436px" /></a></p>
<p>And we can see the uploaded documents using the Console as well.</p>
</div>
</div>
<div align="left">
<h3><a href="https://blog.falafel.com/wp-content/uploads/2017/01/demo3.png" rel="prettyPhoto[gallery-VWjZ]"><img class="alignnone wp-image-6082 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/demo3.png" width="681" height="139" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/demo3.png 681w, https://blog.falafel.com/wp-content/uploads/2017/01/demo3-300x61.png 300w" sizes="(max-width: 681px) 100vw, 681px" /></a></h3>
<h3>Google Cloud SQL</h3>
<div>Google Cloud SQL is our first structured Cloud storage option. This is your <a href="https://cloud.google.com/sql/" target="_blank">full-featured MySQL database service, for relational data in the cloud, managed by Google</a>. If you come from a .NET background and aren&#8217;t familiar with MySQL, you may want to read up on it to get started <a href="https://cloud.google.com/sql/">https://cloud.google.com/sql/</a>. MySQL is the most popular open-source, cross-platform relational database, and it is the relational-data storage mechanism of choice for Google itself, as well as well-known heavy hitters like Facebook and Adobe. If you are &#8220;all-in&#8221; with Google Cloud, take a good look at MySQL, because you will probably find the most experience, documentation, and integrations with the rest of Google Cloud start with Google Cloud SQL.</div>
<div></div>
<div>To create a Cloud SQL Instance, navigate to the SQL option in the GCP Console and choose Create instance.</div>
<div><a href="https://blog.falafel.com/wp-content/uploads/2017/01/sql1.png" rel="prettyPhoto[gallery-VWjZ]"><img class="alignnone wp-image-6083" src="https://blog.falafel.com/wp-content/uploads/2017/01/sql1.png" width="287" height="217" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/sql1.png 596w, https://blog.falafel.com/wp-content/uploads/2017/01/sql1-300x227.png 300w" sizes="(max-width: 287px) 100vw, 287px" /></a>    <a href="https://blog.falafel.com/wp-content/uploads/2017/01/sql2.png" rel="prettyPhoto[gallery-VWjZ]"><img class="alignnone wp-image-6084" src="https://blog.falafel.com/wp-content/uploads/2017/01/sql2.png" width="376" height="214" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/sql2.png 831w, https://blog.falafel.com/wp-content/uploads/2017/01/sql2-300x171.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/sql2-768x438.png 768w" sizes="(max-width: 376px) 100vw, 376px" /></a></div>
<div> I&#8217;m selecting the Second Generation option.</div>
<div><a href="https://blog.falafel.com/wp-content/uploads/2017/01/sql3.png" rel="prettyPhoto[gallery-VWjZ]"><img class="alignnone wp-image-6085" src="https://blog.falafel.com/wp-content/uploads/2017/01/sql3.png" width="480" height="242" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/sql3.png 895w, https://blog.falafel.com/wp-content/uploads/2017/01/sql3-300x151.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/sql3-768x387.png 768w" sizes="(max-width: 480px) 100vw, 480px" /></a></div>
<div>You can add a name and leave the default selections, then choose Create. Or, you can use this gcloud command:</div>
<div>
<pre class="crayon-plain-tag">gcloud beta sql instances create instance1 --tier=db-n1-standard-8 --activation-policy=ALWAYS</pre>
</div>
<div>Using either method, you should now be able to see the new instance in the Console.</div>
<div> <a href="https://blog.falafel.com/wp-content/uploads/2017/01/sql4.png" rel="prettyPhoto[gallery-VWjZ]"><img class="alignnone wp-image-6086 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/sql4.png" width="841" height="152" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/sql4.png 841w, https://blog.falafel.com/wp-content/uploads/2017/01/sql4-300x54.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/sql4-768x139.png 768w" sizes="(max-width: 841px) 100vw, 841px" /></a></div>
<div>Keeping with our .NET theme, I&#8217;ll also show you how to connect to the new Google Cloud SQL instance using Visual Studio.</div>
<div>
<h3>First Steps</h3>
</div>
<div>Here&#8217;s what you&#8217;ll need:</div>
<div><a href="http://dev.mysql.com/downloads/connector/odbc/" target="_blank">MySQL ODBC connector</a></div>
<div><a href="https://cloud.google.com/visual-studio/" target="_blank">Cloud Tools for Visual Studio</a> , <a href="https://cloud.google.com/tools/visual-studio/docs/quickstart#create_an_aspnet_app" target="_blank">authenticated and connected to the same project as the Cloud SQL instance</a></div>
<div><a href="https://www.mysql.com/why-mysql/windows/visualstudio/" target="_blank">MySQL tools for Visual Studio</a></div>
<div></div>
<div>Using the Cloud Tools Google Cloud Explorer, you should be able to see the instance under the Google Cloud SQL heading.</div>
<div><a href="https://blog.falafel.com/wp-content/uploads/2017/01/sql5.png" rel="prettyPhoto[gallery-VWjZ]"><img class="alignnone wp-image-6087" src="https://blog.falafel.com/wp-content/uploads/2017/01/sql5.png" width="267" height="191" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/sql5.png 489w, https://blog.falafel.com/wp-content/uploads/2017/01/sql5-300x215.png 300w" sizes="(max-width: 267px) 100vw, 267px" /></a></div>
<div>But before we can connect, we need to allow connections from our development machine. The following gcloud commands will add a single IP address to the authorized networks list (use your local IP to connect from your local machine), and set the root user&#8217;s password, where instance1 is the Cloud SQL instance name.</div>
<pre class="crayon-plain-tag">gcloud sql instances set-root-password instance1 --password=[newpassword]
gcloud sql instances patch instance1 --authorized-networks=[myipaddress]</pre>
<div>You can learn more about the patch and other <a href="https://cloud.google.com/sdk/gcloud/reference/sql/instances/" target="_blank">instance commands here</a>.</div>
<div></div>
<div>Once your IP address is allowed, you can use the root user and the password you just created to add a connection in Visual Studio, just as you would for any other database.</div>
<div><a href="https://blog.falafel.com/wp-content/uploads/2017/01/sql6.png" rel="prettyPhoto[gallery-VWjZ]"><img class="alignnone wp-image-6088" src="https://blog.falafel.com/wp-content/uploads/2017/01/sql6.png" width="350" height="361" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/sql6.png 728w, https://blog.falafel.com/wp-content/uploads/2017/01/sql6-291x300.png 291w" sizes="(max-width: 350px) 100vw, 350px" /></a></div>
<div></div>
<div>Now you will see the instance inside Visual Studio&#8217;s Server Explorer. Just to show that we can &#8211; let&#8217;s add a table with an int column, by right clicking and creating a new query with the text</div>
<div>
<pre class="crayon-plain-tag">create table testtable1 (col int)</pre>
</div>
</div>
<div>Now you can see the table and column in Visual Studio&#8217;s Server Explorer as well.</div>
<div><a href="https://blog.falafel.com/wp-content/uploads/2017/01/sql7.png" rel="prettyPhoto[gallery-VWjZ]"><img class="alignnone wp-image-6089" src="https://blog.falafel.com/wp-content/uploads/2017/01/sql7.png" width="312" height="294" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/sql7.png 593w, https://blog.falafel.com/wp-content/uploads/2017/01/sql7-300x282.png 300w" sizes="(max-width: 312px) 100vw, 312px" /></a></div>
<div>Of course if you don&#8217;t like Visual Studio, any IDE that works with MySQL will work, including the <a href="https://dev.mysql.com/doc/refman/5.7/en/mysql.html" target="_blank">MySQL Command line Tool</a>.</div>
<div></div>
<div>But if you DO like Visual Studio, and you&#8217;d like to see this example continued to show how to use Entity Framework with your new Google Cloud SQL instance, <a href="https://blog.falafel.com/entity-framework-google-cloud-sql/" target="_blank">check out this other post in our series</a>.</div>
<div></div>
<div>In Part 2 of this post, we will look at 2 more Cloud Storage options &#8211; Google BigTable and Google DataStore.</div>
<h3>Other Resources</h3>
<div><a href="https://www.youtube.com/watch?v=mmjuMyRBPO4" target="_blank">Video Overview of Cloud Storage Options</a></div>
<div><a href="https://cloud.google.com/storage/docs/reference/libraries" target="_blank">Cloud Storage Client Libraries</a></div>
<div><a href="https://developers.google.com/gdata/client-cs" target="_blank">.NET Client Library Developer&#8217;s Guide</a></div>
<div><a href="https://cloud.google.com/dotnet/docs/getting-started/using-cloud-storage" target="_blank">Using Cloud Storage with .NET</a></div>
<div><a href="https://github.com/GoogleCloudPlatform/dotnet-docs-samples/tree/quickstarts" target="_blank">Google Cloud .NET Code Sample Quickstarts</a></div>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/cloud-storage-options-part-1/">Cloud Storage Options Part 1</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/cloud-storage-options-part-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6072</post-id>	</item>
		<item>
		<title>SQL Server in the Google Cloud</title>
		<link>https://blog.falafel.com/sql-server-google-cloud/</link>
		<comments>https://blog.falafel.com/sql-server-google-cloud/#respond</comments>
		<pubDate>Mon, 30 Jan 2017 14:00:41 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[Cloud Platform]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[GCP]]></category>
		<category><![CDATA[Google Cloud]]></category>
		<category><![CDATA[Google Cloud for the .NET Developer]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6049</guid>
		<description><![CDATA[<p>If you are planning to or even considering jumping in to Google Cloud Platform and you work with .NET technologies, you'll almost certainly want to know how to run SQL Server in the Google Cloud. Google Cloud has made a big effort lately to more fully support the .NET stack, including SQL Server. This is good news for everyone, because more options means more chances to find the right fit for your development project!</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/sql-server-google-cloud/">SQL Server in the Google Cloud</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<aside class="wp-post-series-box series-google-cloud-for-the-net-developer">
	<p class="wp-post-series-name">
		This is post 11 of 17 in the series <em>&ldquo;Google Cloud for the .NET Developer&rdquo;</em>	</p>

	
	</aside>
<p>If you are planning to or even considering jumping in to Google Cloud Platform and you work with .NET technologies, you&#8217;ll almost certainly want to know how to run SQL Server in the Google Cloud. Google Cloud has made a big effort lately to more fully support the .NET stack, including SQL Server. This is good news for everyone, because more options means more chances to find the right fit for your development project!</p>
<h4>Why Run SQL Server in the Google Cloud?</h4>
<p>There could be multiple answers to this question, but here are a couple to consider: If you are maintaining or migrating a production solution, you might be looking to take advantage of other services in the Google Cloud Platform. And you may already have a SQL server instance or instances as a part of your stack.</p>
<p>In that case, you&#8217;ll have to consider your current deployment strategy against the GCP offerings. Knowing that you <a href="https://cloud.google.com/sql-server/" target="_blank">CAN run SQL Server on Google Cloud</a> is a good start! You will also want to consider licensing &#8211; if you are already running on another cloud platform you are probably already familiar with how that works, particularly if<a href="https://cloud.google.com/compute/docs/instances/windows/ms-licensing" target="_blank"> you already use Microsoft License Mobility</a>.</p>
<p>Note that there are different pricing levels for SQL Server Express, Standard, and Web, and that currently Enterprise is &#8220;Coming Soon&#8221;. What&#8217;s interesting and might be a game changer for some customers, is that using SQL Server on Google Cloud lets you pay-as-you-go for SQL Server licensing, just as you do for other cloud resources. So <a href="https://www.microsoft.com/en-us/sql-server/sql-server-2016-pricing" target="_blank">take a look at regular licensing fees for SQL server</a> and you&#8217;ll see why that might be a good choice!</p>
<p>But the case I want to consider first is a little more developer-centered. How would a .NET developer who is just getting started with Google Cloud Platform go about setting up a simple SQL Server instance on a VM and connect to it? This is a great exercise in taking something you probably already know &#8211; how to set up and connect to a SQL Server instance for development, except do it on GCP.</p>
<h4>Before You Start</h4>
<p>Before you get started, there are a couple of pieces you need to have ready:</p>
<ul>
<li>SQL Server Management Studio installed on an accessible machine. Since we will be testing with SQL Server 2016,<a href="https://msdn.microsoft.com/en-us/library/mt238290.aspx" target="_blank"> you can download SSMS for free here</a></li>
<li>A Google Cloud account &#8211; just <a href="https://cloud.google.com/free-trial/" target="_blank">sign up and get 60 days and $300 in credits right away </a></li>
<li>A GCP Project <a href="https://cloud.google.com/compute/docs/instances/create-start-instance" target="_blank">already created to house our instance </a> &#8211; learn more about <a href="https://cloud.google.com/compute/docs/projects" target="_blank">Projects in Google Cloud here</a></li>
</ul>
<h4>Creating the SQL Server Instance</h4>
<p>From the Console, choose VM Instances and Create Instance.<br />
<a href="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver7.png" rel="prettyPhoto[gallery-02oV]"><br />
<img class="alignnone" src="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver7.png" alt="" width="550" height="162" /><br />
</a><br />
Now we must choose options for our VM. If you&#8217;re familiar with this process in Azure, you may want a reference to the recommended machine configurations for SQL Server.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/azuresqlserver.png" rel="prettyPhoto[gallery-02oV]"><img class="alignnone wp-image-6051 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/azuresqlserver.png" width="1109" height="693" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/azuresqlserver.png 1109w, https://blog.falafel.com/wp-content/uploads/2017/01/azuresqlserver-300x187.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/azuresqlserver-768x480.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/azuresqlserver-1024x640.png 1024w" sizes="(max-width: 1109px) 100vw, 1109px" /></a></p>
<p>To get something comparable to the most economical option from the Azure recommendations (DS12_V2), let&#8217;s choose the n1-highmem-4 configuration for Google Cloud.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver3.png" rel="prettyPhoto[gallery-02oV]"><img class="alignnone wp-image-6052 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver3.png" width="925" height="1305" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver3.png 925w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver3-213x300.png 213w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver3-768x1084.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver3-726x1024.png 726w" sizes="(max-width: 925px) 100vw, 925px" /></a></p>
<p>Next, set the boot disk to an image with SQL Server pre-installed. Choose Change on the Boot Disk section, and then select the Application images tab in the Boot disk menu.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver4-e1483728693968.png" rel="prettyPhoto[gallery-02oV]"><img class="alignnone wp-image-6053 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver4-e1483728693968.png" width="1070" height="864" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver4-e1483728693968.png 1070w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver4-e1483728693968-300x242.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver4-e1483728693968-768x620.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver4-e1483728693968-1024x827.png 1024w" sizes="(max-width: 1070px) 100vw, 1070px" /></a></p>
<p>Now you can select the SQL Server image of your choice. We can leave the other options as-is and click Create. Once the instance is created (which you&#8217;ll notice is lightning fast!), you can select the new VM in your instances list.</p>
<p>Then choose Create or reset Windows password. Make SURE to note the account name and password somewhere safe, you will need them to access this VM. But if you misplace them, this is also how you can reset the Windows password.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver9.png" rel="prettyPhoto[gallery-02oV]"><img class="alignnone wp-image-6056 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver9.png" width="1211" height="240" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver9.png 1211w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver9-300x59.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver9-768x152.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver9-1024x203.png 1024w" sizes="(max-width: 1211px) 100vw, 1211px" /></a></p>
<h4>Connect to the VM</h4>
<p>Now we can remotely connect to the VM. Click the RDP button on the instance page. If you haven&#8217;t already, this is a good time to install the <a href="https://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=1&amp;cad=rja&amp;uact=8&amp;ved=0ahUKEwjSkdmKna7RAhXor1QKHfGsCaQQFggcMAA&amp;url=https%3A%2F%2Fchrome.google.com%2Fwebstore%2Fdetail%2Fchrome-remote-desktop%2Fgbchcmhmhahfdphkhkmpfmihenigjmpp%3Fhl%3Den&amp;usg=AFQjCNEuGk15vuDjTteKZQK7QRCwTCs9Mg&amp;sig2=THkXpHZth0CbglZwvpc-cQ" target="_blank">Chrome RDP Extension</a>! You can also download the RDP file to connect using the Windows client.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver10.png" rel="prettyPhoto[gallery-02oV]"><img class="alignnone wp-image-6057 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver10.png" width="1028" height="610" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver10.png 1028w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver10-300x178.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver10-768x456.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver10-1024x608.png 1024w" sizes="(max-width: 1028px) 100vw, 1028px" /></a></p>
<p>Now you can enter the credentials you created for the Windows account. Then you should be able to see the server manager for your new Windows Server VM, and verify that SQL Server is running.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver12.png" rel="prettyPhoto[gallery-02oV]"><img class="alignnone wp-image-6058 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver12.png" width="1275" height="691" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver12.png 1275w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver12-300x163.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver12-768x416.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver12-1024x555.png 1024w" sizes="(max-width: 1275px) 100vw, 1275px" /></a></p>
<h4>Configuring for a Development Connection</h4>
<p>At this point, if you want to alter any of the SQL Server features, you can access the SQL Server installer directly on the VM. You can also open SSMS. Here I just typed SQL into the windows search to bring up these two options. They are both available by default, just because we chose the SQL Server image for our VM.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver13.png" rel="prettyPhoto[gallery-02oV]"><img class="alignnone wp-image-6059 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver13.png" width="394" height="683" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver13.png 394w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver13-173x300.png 173w" sizes="(max-width: 394px) 100vw, 394px" /></a></p>
<p>Open SSMS and use the preset windows authentication login. Now we can change settings directly on our SQL Server instance, just as we would using SSMS locally. For the rest of our example, we are going to set up this SQL server instance as if we wanted to connect from our local machine for development. This isn&#8217;t necessarily something you would need for production, but instead lets us see how to make familiar changes to SQL Server even when running on Google Cloud. If we want to enable the sa account for development purposes, we will need to enable SQL Server authentication by selecting properties and then the security tab.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver14.png" rel="prettyPhoto[gallery-02oV]"><img class="alignnone wp-image-6060 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver14.png" width="373" height="472" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver14.png 373w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver14-237x300.png 237w" sizes="(max-width: 373px) 100vw, 373px" /></a></p>
<p>Then turn on SQL Server and Windows Authentication mode.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver23.png" rel="prettyPhoto[gallery-02oV]"><img class="alignnone wp-image-6067 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver23.png" width="1381" height="324" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver23.png 1381w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver23-300x70.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver23-768x180.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver23-1024x240.png 1024w" sizes="(max-width: 1381px) 100vw, 1381px" /></a></p>
<p>We also have to expand the Logins folder and select sa &gt;properties to set a password. Under Status, select Enabled to turn the account on. It is a good idea to restart after this step and test the login.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver16.png" rel="prettyPhoto[gallery-02oV]"><img class="alignnone wp-image-6062 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver16.png" width="693" height="625" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver16.png 693w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver16-300x271.png 300w" sizes="(max-width: 693px) 100vw, 693px" /></a></p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver17.png" rel="prettyPhoto[gallery-02oV]"><img class="alignnone wp-image-6063 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver17.png" width="690" height="624" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver17.png 690w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver17-300x271.png 300w" sizes="(max-width: 690px) 100vw, 690px" /></a></p>
<h4>Enable External Access to SQL Server</h4>
<p>If we want to access this SQL server instance from outside the VM, we have to add a firewall rule.  The default SQL Server installation included in the image is already set up from the VM side, so we just need to allow connections via the networking configuration. Under Compute &gt; Networking from the Console menu, we can see the current firewall rules and also add a new one to allow connections to port 1433 for SQL Server.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver19.png" rel="prettyPhoto[gallery-02oV]"><img class="alignnone wp-image-6064 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver19.png" width="636" height="687" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver19.png 636w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver19-278x300.png 278w" sizes="(max-width: 636px) 100vw, 636px" /></a></p>
<p>You can set the firewall rule to be as open or restrictive as you like &#8211; &#8220;allow from any source&#8221; will work for any IP, you can add a range, or<a href="http://www.myipaddress.com/show-my-ip-address/" target="_blank"> simply your development machine&#8217;s IP</a>. To add a single IP choose the option for IP ranges &#8211; single values are also allowed, and no subnet mask is required.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver24.png" rel="prettyPhoto[gallery-02oV]"><img class="alignnone wp-image-6069 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver24.png" width="1182" height="1065" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver24.png 1182w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver24-300x270.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver24-768x692.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver24-1024x923.png 1024w" sizes="(max-width: 1182px) 100vw, 1182px" /></a><img class="alignnone size-full wp-image-6070" src="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver25.png" alt="" width="1488" height="727" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver25.png 1488w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver25-300x147.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver25-768x375.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver25-1024x500.png 1024w" sizes="(max-width: 1488px) 100vw, 1488px" /></p>
<p>We&#8217;re almost there! To connect from a local SSMS, you&#8217;ll need the external IP of the VM. Go to External IP Addresses in the console and copy that address.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver21.png" rel="prettyPhoto[gallery-02oV]"><img class="alignnone wp-image-6066 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver21.png" width="2142" height="409" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver21.png 2142w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver21-300x57.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver21-768x147.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/gcp_sqlserver21-1024x196.png 1024w" sizes="(max-width: 2142px) 100vw, 2142px" /></a></p>
<p>Finally, use that IP and your SQL Server Authentication credentials to connect from your local machine. Now you can use that connection to set up connection strings in your web.config files or anywhere you would normally use SQL credentials in your development process.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/2017-01-06-12_39_29-gcp_sqlserver22.png" rel="prettyPhoto[gallery-02oV]"><img class="alignnone wp-image-6050 size-medium" src="https://blog.falafel.com/wp-content/uploads/2017/01/2017-01-06-12_39_29-gcp_sqlserver22-300x197.png" width="300" height="197" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/2017-01-06-12_39_29-gcp_sqlserver22-300x197.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/2017-01-06-12_39_29-gcp_sqlserver22-768x503.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/2017-01-06-12_39_29-gcp_sqlserver22.png 949w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<h4>More Resources</h4>
<p>Google has some great related tutorials that you may also want to check out:<br />
<a href="https://cloud.google.com/compute/docs/tutorials/creating-high-performance-sql-server-instance" target="_blank">Creating a High-Performance SQL Server Instance </a><br />
<a href="https://cloud.google.com/compute/docs/instances/sql-server/best-practices" target="_blank">Best Practices for SQL Server Instances</a><br />
<a href="https://cloudplatform.googleblog.com/2016/08/SQL-server-images-on-Google-Compute-Engine.html" target="_blank">SQL Server images on Google Computer Engine</a></p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/sql-server-google-cloud/">SQL Server in the Google Cloud</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/sql-server-google-cloud/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6049</post-id>	</item>
		<item>
		<title>Pub/Sub Part 2 : REST-based Google Cloud Pub/Sub with OAuth and C#</title>
		<link>https://blog.falafel.com/rest-google-cloud-pubsub-with-oauth/</link>
		<comments>https://blog.falafel.com/rest-google-cloud-pubsub-with-oauth/#respond</comments>
		<pubDate>Fri, 27 Jan 2017 14:00:28 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Cloud Platform]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Google Cloud]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>
		<category><![CDATA[Pub/Sub]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=5998</guid>
		<description><![CDATA[<p>This is post 10 of 17 in the series &#8220;Google Cloud for the .NET Developer&#8221; Pub/Sub is an increasingly popular component of many cloud-driven solutions. Producers publish messages to a topic, and subscribers consume them typically triggering some type of work. Pub/Sub queues are also very important when it comes to high-throughput data ingress, typically synonymous with IoT solutions. I will show you how to publish to and consume messages on the Google Cloud Platform using the REST-based API, authenticated with OAuth and using C#. Getting Started If you haven&#8217;t already, create a Google Cloud account (they offer a 60...</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/rest-google-cloud-pubsub-with-oauth/">Pub/Sub Part 2 : REST-based Google Cloud Pub/Sub with OAuth and C#</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<aside class="wp-post-series-box series-google-cloud-for-the-net-developer">
	<p class="wp-post-series-name">
		This is post 10 of 17 in the series <em>&ldquo;Google Cloud for the .NET Developer&rdquo;</em>	</p>

	
	</aside>
<div>Pub/Sub is an increasingly popular component of many cloud-driven solutions. Producers publish messages to a topic, and subscribers consume them typically triggering some type of work. Pub/Sub queues are also very important when it comes to high-throughput data ingress, typically synonymous with IoT solutions. I will show you how to publish to and consume messages on the Google Cloud Platform using the REST-based API, authenticated with OAuth and using C#.</div>
<h2>Getting Started</h2>
<div>If you haven&#8217;t already, create a <a href="http://cloud.google.com">Google Cloud account </a>(they offer a 60 day free trial with a $300 credit). You will then need to create a project. A project is exactly what it sounds like, it&#8217;s an encapsulation of all the technologies organized by project, I&#8217;ve named mine CSharpPubSub. From the upper left hamburger menu in the console select Pub/Sub, enable the API (if you haven&#8217;t done this yet), then create a topic that will be used throughout this article.</div>
<div></div>
<div>
<div id="attachment_5999" style="width: 1033px" class="wp-caption aligncenter"><a href="http://blog.falafel.com/wp-content/uploads/2016/12/createtopic.jpg" rel="prettyPhoto[gallery-Wa1l]"><img class="size-full wp-image-5999" src="http://blog.falafel.com/wp-content/uploads/2016/12/createtopic.jpg" alt="Creating a Pub/Sub Topic" width="1023" height="328" srcset="https://blog.falafel.com/wp-content/uploads/2016/12/createtopic.jpg 1023w, https://blog.falafel.com/wp-content/uploads/2016/12/createtopic-300x96.jpg 300w, https://blog.falafel.com/wp-content/uploads/2016/12/createtopic-768x246.jpg 768w" sizes="(max-width: 1023px) 100vw, 1023px" /></a><p class="wp-caption-text">Creating a Pub/Sub Topic</p></div>
<p>&nbsp;</p>
<p>Next you will need to create a service account to authenticate to Pub/Sub with. Please review this &lt;LINK&gt;post&lt;/LINK&gt; for instructions on how to do so. The service account will require the Pub/Sub Editor role, as we will be creating a subscription to our topic. Be sure to make a copy of the credential helper class located at the bottom of the post for our use in this example. The scope we will be authenticating to will be https://www.googleapis.com/auth/pubsub .</p>
</div>
<h2>Pub/Sub Topic Subscriptions</h2>
<div>There are two types of consumers of a GCP topic, one is a Push subscription, the other is a Pull subscription. Both are alike in the sense that they are subscriptions to a Pub/Sub topic, but where they differ is in how they behave. When a Push subscription is created, it is supplied with an http endpoint that works as a callback when a message is published onto the topic. A Pull subscription is used when an http endpoint is not available, this is also the typical model used when implementing a polling based-solution on the topic. In this example, I will be providing a helper class that will allow you to publish to a GCP Pub/Sub topic, as well as use a pull subscription to consume messages from a topic, this way a callback endpoint is not required.</div>
<div></div>
<div>
<div id="attachment_6000" style="width: 495px" class="wp-caption aligncenter"><a href="http://blog.falafel.com/wp-content/uploads/2016/12/PubSub.jpg" rel="prettyPhoto[gallery-Wa1l]"><img class="size-full wp-image-6000" src="http://blog.falafel.com/wp-content/uploads/2016/12/PubSub.jpg" alt="GCP Pub/Sub" width="485" height="324" srcset="https://blog.falafel.com/wp-content/uploads/2016/12/PubSub.jpg 485w, https://blog.falafel.com/wp-content/uploads/2016/12/PubSub-300x200.jpg 300w" sizes="(max-width: 485px) 100vw, 485px" /></a><p class="wp-caption-text">GCP Pub/Sub</p></div>
</div>
<div></div>
<h2>The Pub/Sub Message</h2>
<div>A Pub/Sub message takes the form of a Base64 encoded message, as well as a key/value pair collection of attributes. These attributes can be anything, in our case we will be using the properties of a POCO object as our attributes. Pub/Sub messages from the REST-ful API also contain fields for a MessageId and PublishTime, both of which are populated by the server upon receiving the message.</div>
<h2>Pull Subscription Helper Class</h2>
<div>Find below the listing of a helper class that will make publishing and consuming to Google Cloud Platform Pub/Sub topics easy. This class makes use of the GCP_OAuth_ServiceCredential class to handle the OAuth authentication of the REST-ful API calls. This class also handles the creation of a topic subscription on the Google Cloud Platform (hence needing the service acccount to have the Pub/Sub editor role). This class uses generics to take any serializable type T to publish and consume as attributes in a Pub/Sub message. As we are using a Pull subscription, you will also notice code acknowledging the receipt of messages from the topic.</div>
<div></div>
<div>
<pre class="crayon-plain-tag">using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace FalafelDev
{

    public class GCP_OAuth_Restful_Pull_PubSub&lt;T&gt; 
    {
        private string _rootUrl = "https://pubsub.googleapis.com";
        private string _projectName;
        private string _topicName;
        private string _subscriptionName;
        private GCP_OAuth_ServiceCredential _credential;     
  
        public GCP_OAuth_Restful_Pull_PubSub(GCP_OAuth_ServiceCredential credential, string projectName, 
                   string topicName, string desiredSubscriptionName="")
        {
            this._credential = credential;
            this._projectName = projectName;
            this._topicName = $"projects/{projectName}/topics/{topicName}";
            this._subscriptionName = $"projects/{projectName}/subscriptions/{desiredSubscriptionName}";            
        }

        /// &lt;summary&gt;
        /// Obtains Auth0 token and creates subscription queue if needed
        /// &lt;/summary&gt;
        /// &lt;returns&gt;true if successful&lt;/returns&gt;
        public async Task&lt;bool&gt; Initialize()
        {
            return await _createSubscription();
        }

        public async Task&lt;List&lt;string&gt;&gt; PublishMessage(T data)
        { 
            //topic format -&gt; projects/csharppubsub/topics/demoData 
            string endpoint = _rootUrl + $"/v1/{_topicName}:publish";

            PubSubMessage psm = new PubSubMessage();
            psm.Attributes = data;
            //psm.Data ="Hello World".EncodeBase64(); &lt;-- optionally include b64 encoded message

            PublishMessageRequest message = new PublishMessageRequest();
            message.Messages = new List&lt;PubSubMessage&gt; { psm };

            string json = JsonConvert.SerializeObject(message, 
                new JsonSerializerSettings { ContractResolver = 
                new CamelCasePropertyNamesContractResolver() });

            StringContent content = new StringContent(json);
            var httpClient = await _credential.GetHttpClient();
            if (httpClient != null)
            {
                var response = await httpClient.PostAsync(endpoint, content);
                string jsonResult = await response.Content.ReadAsStringAsync();
                var result = JsonConvert.DeserializeObject&lt;PublishMessageResponse&gt;(jsonResult);
                if (result == null || result.MessageIds == null || result.MessageIds.Count == 0)
                {
                    return new List&lt;string&gt;();
                }
                else
                {
                    return result.MessageIds;
                }
            }
            return null;
        }

        public async Task&lt;List&lt;T&gt;&gt; PullMessages(int maxMessages)
        {
            string endpoint = _rootUrl + $"/v1/{_subscriptionName}:pull";

            PullSubscriptionRequest message = new PullSubscriptionRequest();
            message.ReturnImmediately = true;
            message.MaxMessages = maxMessages;

            string json = JsonConvert.SerializeObject(message, 
                new JsonSerializerSettings { ContractResolver = 
                new CamelCasePropertyNamesContractResolver() });

            StringContent content = new StringContent(json);
            var httpClient = await _credential.GetHttpClient();
            if(httpClient != null)
            {
                var response = await httpClient.PostAsync(endpoint, content);
                string jsonResult = await response.Content.ReadAsStringAsync();
                var result = JsonConvert.DeserializeObject&lt;PullSubscriptionResponse&gt;(jsonResult);
                if(result == null || result.ReceivedMessages==null || result.ReceivedMessages.Count == 0)
                {
                    return new List&lt;T&gt;();
                }
                else
                {
                    List&lt;string&gt; ackIds = result.ReceivedMessages.Select(x =&gt; x.AckId).ToList();
                    var retValue = result.ReceivedMessages.Select(x =&gt; x.Message.Attributes).ToList();
                    
                    /* var strings = result.ReceivedMessages.Select(x =&gt; x.Message.Data.DecodeBase64())
                               .ToList(); &lt;-- optional retrieve b64 encrypted message */

                    await _acknowledgeMessages(ackIds);
                    return retValue;
                }
            }
            return null;
        }

        private async Task&lt;bool&gt; _acknowledgeMessages(List&lt;string&gt; ackIds)
        {
            string endpoint = _rootUrl + $"/v1/{_subscriptionName}:acknowledge";

            AcknowledgeMessageRequest message = new AcknowledgeMessageRequest();
            message.AckIds = ackIds;

            string json = JsonConvert.SerializeObject(message, 
                new JsonSerializerSettings { ContractResolver = 
                new CamelCasePropertyNamesContractResolver() });

            StringContent content = new StringContent(json);
            var httpClient = await _credential.GetHttpClient();
            if (httpClient != null)
            {
                var response = await httpClient.PostAsync(endpoint, content);
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    return true;
                }
            }
            return false;
        }

        private async Task&lt;bool&gt; _createSubscription()
        {
            //subscription name format projects/csharppubsub/subscriptions/CSHARP
            var endpoint = _rootUrl + $"/v1/{_subscriptionName}";

            CreateSubscriptionRequest message = new CreateSubscriptionRequest();
            message.Topic = _topicName;
            message.AckDeadlineSeconds = 60;

            string json = JsonConvert.SerializeObject(message,
                new JsonSerializerSettings { ContractResolver = 
                new CamelCasePropertyNamesContractResolver() });

            StringContent content = new StringContent(json);
            var httpClient = await _credential.GetHttpClient();
            if (httpClient != null)
            {
                var response = await httpClient.PutAsync(endpoint, content);
                //conflict is returned if subscription already exists
                if(response.StatusCode== HttpStatusCode.OK || 
                    response.StatusCode == HttpStatusCode.Conflict)
                {
                    return true;
                }
            }
            return false;
        }

 
        /* Google Cloud Platform Pub/Sub REST Api Models for Deserialization */
        internal class PubSubMessage
        {
            //base64 encoded
            public string Data { get; set; }
            public T Attributes { get; set; }
            public string MessageId { get; set; }
            public DateTime? PublishTime { get; set; }
        }

        internal class CreateSubscriptionRequest
        {
            public string Topic { get; set; }
            public object PushConfig = null;
            public int AckDeadlineSeconds { get; set; }

        }

        internal class PullSubscriptionRequest
        {
            public bool ReturnImmediately { get; set; }
            public int MaxMessages { get; set; }
        }

        internal class PullSubscriptionResponse
        {
            public List&lt;ReceivedMessage&gt; ReceivedMessages { get; set; }
        }

        internal class PublishMessageRequest
        {
            public List&lt;PubSubMessage&gt; Messages { get; set; }
        }

        internal class PublishMessageResponse
        {
            public List&lt;string&gt; MessageIds { get; set; }
        }

        internal class ReceivedMessage
        {
            public string AckId { get; set; }
            public PubSubMessage Message { get; set; }
        }

        internal class AcknowledgeMessageRequest
        {
            public List&lt;string&gt; AckIds { get; set; }
        }
        
    }
}</pre>
<h2>Example Usage</h2>
</div>
<div>Create a new console application, and bring in both the GCP_OAuth_ServiceCredential and GCP_OAuth_Retful_Pull_PubSub classes. Don&#8217;t forget the P12 key file for the Service account credentials! Now we need a class to be used as the key/value attributes of the message. In my case, I created the following simple class:</div>
<div>
<pre class="crayon-plain-tag">public class MyObject
{
    public string MyName { get; set; }
    public string MyChild { get; set; }
}</pre>
Next add the following static method to the Program.cs file, this method instantiates the service credentials, as well as publishes messages, and pulls them (and in turn acknowledges) from the topic:</p>
</div>
<div>
<pre class="crayon-plain-tag">private static async Task GoogleCloudPullPubSub()
{
    string serviceAccountEmail = "pubsubsvcacct-cert@csharppubsub.iam.gserviceaccount.com";
    string p12CertificatePath = "CSharpPubSub-37ef513cf864.p12";
    string projectName = "csharppubsub";
    string topicName = "demoData";
    string subscriptionName = "CSHARP";

    GCP_OAuth_ServiceCredential credential = new GCP_OAuth_ServiceCredential(serviceAccountEmail, 
        p12CertificatePath, new List&lt;string&gt; { "https://www.googleapis.com/auth/pubsub" });
    GCP_OAuth_Restful_Pull_PubSub&lt;MyObject&gt; pubsub = new GCP_OAuth_Restful_Pull_PubSub&lt;MyObject&gt;(credential, 
        projectName, topicName, subscriptionName);

    //initialize when ready to start interacting with the GCP Topic
    bool isInitialized = await pubsub.Initialize();
    if (isInitialized)
    {
        var messageIds = await pubsub.PublishMessage(
            new MyObject { MyName = "Carey", MyChild = "Hunter" });
        var myObjects = await pubsub.PullMessages(100);

        foreach(var obj in myObjects)
        {
            Console.WriteLine($"My Name: {obj.MyName}, My Child: {obj.MyChild}");
        }
    }
}</pre>
Finally, call this method from your main method:</p>
</div>
<div>
<pre class="crayon-plain-tag">GoogleCloudPullPubSub().Wait();
Console.WriteLine("FINISHED");
Console.ReadLine();</pre>
<div id="attachment_6001" style="width: 991px" class="wp-caption aligncenter"><a href="http://blog.falafel.com/wp-content/uploads/2016/12/pubsubconsole.jpg" rel="prettyPhoto[gallery-Wa1l]"><img class="size-full wp-image-6001" src="http://blog.falafel.com/wp-content/uploads/2016/12/pubsubconsole.jpg" alt="Restful Pub/Sub Console" width="981" height="513" srcset="https://blog.falafel.com/wp-content/uploads/2016/12/pubsubconsole.jpg 981w, https://blog.falafel.com/wp-content/uploads/2016/12/pubsubconsole-300x157.jpg 300w, https://blog.falafel.com/wp-content/uploads/2016/12/pubsubconsole-768x402.jpg 768w" sizes="(max-width: 981px) 100vw, 981px" /></a><p class="wp-caption-text">Restful Pub/Sub Console</p></div>
</div>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/rest-google-cloud-pubsub-with-oauth/">Pub/Sub Part 2 : REST-based Google Cloud Pub/Sub with OAuth and C#</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/rest-google-cloud-pubsub-with-oauth/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">5998</post-id>	</item>
		<item>
		<title>Pub/Sub Part 1 : C# OAuth Authentication to Google Cloud Pub/Sub using a Service Account</title>
		<link>https://blog.falafel.com/oauth-google-cloud-authentication/</link>
		<comments>https://blog.falafel.com/oauth-google-cloud-authentication/#respond</comments>
		<pubDate>Thu, 26 Jan 2017 14:00:41 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Cloud Platform]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[GCP]]></category>
		<category><![CDATA[Google Cloud]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>
		<category><![CDATA[OAuth]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=5989</guid>
		<description><![CDATA[<p>This is post 9 of 17 in the series &#8220;Google Cloud for the .NET Developer&#8221; If you are looking to consume Google Cloud services, you will need to authenticate. In my case, I was looking to use a service account created for a Pub/Sub application that I have in mind. I will walk you through creating a Service Account, downloading a key and authenticating with the Google Cloud Platform using a C# library. The first thing that you will need to do is log into the Google Cloud Platform console (create a project, if you don&#8217;t already have one). From...</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/oauth-google-cloud-authentication/">Pub/Sub Part 1 : C# OAuth Authentication to Google Cloud Pub/Sub using a Service Account</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<aside class="wp-post-series-box series-google-cloud-for-the-net-developer">
	<p class="wp-post-series-name">
		This is post 9 of 17 in the series <em>&ldquo;Google Cloud for the .NET Developer&rdquo;</em>	</p>

	
	</aside>
<div>If you are looking to consume Google Cloud services, you will need to authenticate. In my case, I was looking to use a service account created for a Pub/Sub application that I have in mind. I will walk you through creating a Service Account, downloading a key and authenticating with the Google Cloud Platform using a C# library.</div>
<div>The first thing that you will need to do is log into the <a href="http://cloud.google.com">Google Cloud Platform console</a> (create a project, if you don&#8217;t already have one). From the hamburger menu in the top left, select IAM &amp; Admin.</div>
<div></div>
<div>
<div id="attachment_5991" style="width: 478px" class="wp-caption aligncenter"><a href="http://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_iam_1.jpg" rel="prettyPhoto[gallery-wRCn]"><img class="size-full wp-image-5991" src="http://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_iam_1.jpg" alt="Google Cloud Platform IAM &amp; Admin" width="468" height="519" srcset="https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_iam_1.jpg 468w, https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_iam_1-271x300.jpg 271w" sizes="(max-width: 468px) 100vw, 468px" /></a><p class="wp-caption-text">Google Cloud Platform IAM &amp; Admin</p></div>
</div>
<div></div>
<div>From there, select Service Accounts, then click the button to create a new Service account.</div>
<div></div>
<div>
<div id="attachment_5993" style="width: 884px" class="wp-caption aligncenter"><a href="http://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_svcacct_2.jpg" rel="prettyPhoto[gallery-wRCn]"><img class="size-full wp-image-5993" src="http://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_svcacct_2.jpg" alt="Google Cloud Platform Create Service Account" width="874" height="382" srcset="https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_svcacct_2.jpg 874w, https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_svcacct_2-300x131.jpg 300w, https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_svcacct_2-768x336.jpg 768w" sizes="(max-width: 874px) 100vw, 874px" /></a><p class="wp-caption-text">Google Cloud Platform Create Service Account</p></div>
</div>
<div></div>
<div>In the Create Service Account form, you&#8217;ll need to give the account a meaningful name, as well as assign it to <a href="https://cloud.google.com/iam/docs/understanding-roles">one or more roles</a>. In my case, my service account will need the Pub/Sub editor role. Make note of the service account id email address. Then click the checkbox to furnish a private key, and select the P12 key. Once you are finished, press the Create button, and the private key&#8217;s password will be displayed (it will be notasecret), and a download of the P12 key will begin.</div>
<div></div>
<div>
<div id="attachment_5994" style="width: 657px" class="wp-caption aligncenter"><a href="http://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_svcacct_3.jpg" rel="prettyPhoto[gallery-wRCn]"><img class="size-full wp-image-5994" src="http://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_svcacct_3.jpg" alt="Google Cloud Platform Service Account Creation Form" width="647" height="607" srcset="https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_svcacct_3.jpg 647w, https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_svcacct_3-300x281.jpg 300w" sizes="(max-width: 647px) 100vw, 647px" /></a><p class="wp-caption-text">Google Cloud Platform Service Account Creation Form</p></div>
</div>
<div></div>
<div>Now we are ready to fire up Visual Studio. In this example, we will create a simple console application. I&#8217;ve named my project GcpOAuthConsole.</div>
<div></div>
<div>
<div id="attachment_5997" style="width: 955px" class="wp-caption aligncenter"><a href="http://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_vsproj_4.jpg" rel="prettyPhoto[gallery-wRCn]"><img class="size-full wp-image-5997" src="http://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_vsproj_4.jpg" alt="New Visual Studio Project" width="945" height="655" srcset="https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_vsproj_4.jpg 945w, https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_vsproj_4-300x208.jpg 300w, https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_vsproj_4-768x532.jpg 768w" sizes="(max-width: 945px) 100vw, 945px" /></a><p class="wp-caption-text">New Visual Studio Project</p></div>
</div>
<div></div>
<div>The first thing that is required is to add the Google.Api.Auth package via NuGet to the project.</div>
<div></div>
<div>
<div id="attachment_5995" style="width: 1034px" class="wp-caption aligncenter"><a href="http://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_vsnuget_5.jpg" rel="prettyPhoto[gallery-wRCn]"><img class="size-large wp-image-5995" src="http://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_vsnuget_5-1024x243.jpg" alt="Adding the Google.Apis.Auth NuGet Package" width="1024" height="243" srcset="https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_vsnuget_5-1024x243.jpg 1024w, https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_vsnuget_5-300x71.jpg 300w, https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_vsnuget_5-768x182.jpg 768w, https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_vsnuget_5.jpg 1354w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><p class="wp-caption-text">Adding the Google.Apis.Auth NuGet Package</p></div>
</div>
<div></div>
<div>Next we&#8217;ll add the P12 key file that we downloaded from the Google Cloud Platform console to the project, be sure to set the build action to content, and to Copy Always to the output directory.</div>
<div></div>
<div>
<div id="attachment_5996" style="width: 518px" class="wp-caption aligncenter"><a href="http://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_vsp12_6.jpg" rel="prettyPhoto[gallery-wRCn]"><img class="size-full wp-image-5996" src="http://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_vsp12_6.jpg" alt="Including the Service Account P12 Key in Visual Studio" width="508" height="458" srcset="https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_vsp12_6.jpg 508w, https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_vsp12_6-300x270.jpg 300w" sizes="(max-width: 508px) 100vw, 508px" /></a><p class="wp-caption-text">Including the Service Account P12 Key in Visual Studio</p></div>
</div>
<div></div>
<div>Google authentication uses Scopes to identify the service(s) that an account is authenticating to. Find a listing of available scopes <a href="https://developers.google.com/identity/protocols/googlescopes">here</a>. In my case, I want to authenticate to Google Cloud Pub/Sub API services. My scope will be one of either https://www.googleapis.com/auth/cloud-platform OR https://www.googleapis.com/auth/pubsub . In this example I&#8217;ll use the latter, though either will work.</div>
<div></div>
<div>
<div id="attachment_5992" style="width: 1034px" class="wp-caption aligncenter"><a href="http://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_scope_7.jpg" rel="prettyPhoto[gallery-wRCn]"><img class="size-large wp-image-5992" src="http://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_scope_7-1024x228.jpg" alt="Google Authentication Scopes for Pub/Sub" width="1024" height="228" srcset="https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_scope_7-1024x228.jpg 1024w, https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_scope_7-300x67.jpg 300w, https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_scope_7-768x171.jpg 768w, https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_scope_7.jpg 1097w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><p class="wp-caption-text">Google Authentication Scopes for Pub/Sub</p></div>
</div>
<div></div>
<div>Let&#8217;s dive into some code. Below is a code listing that will authenticate to Google using the P12 key, and receive in return an OAuth token that can be used in subsequent calls to the Google Cloud Platform. Also make note that I&#8217;ve included code to identify if the OAuth token is expired based on the Clock provided by the ServiceAccountCredential object. Add the following using statements to your Program.cs file:</div>
<div>
<pre class="crayon-plain-tag">using Google.Apis.Auth.OAuth2;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;</pre>
Finally, include the following code within the Main method of your console application:</p>
</div>
<div>
<pre class="crayon-plain-tag">Console.WriteLine("Google Cloud Service Account using OAuth Example");

string p12CertificatePath = "CSharpPubSub-c07c67be2080.p12";
string serviceAccountEmail = "oauth-to-gcp-sample@csharppubsub.iam.gserviceaccount.com";
var certificate = new X509Certificate2(p12CertificatePath, "notasecret", X509KeyStorageFlags.Exportable);

var credential = new ServiceAccountCredential(
        new ServiceAccountCredential.Initializer(serviceAccountEmail)
        {
            Scopes = new[] { "https://www.googleapis.com/auth/pubsub" }
        }.FromCertificate(certificate));

credential.RequestAccessTokenAsync(CancellationToken.None).Wait();

Console.WriteLine($"OAuth Token Obtained: {credential.Token.AccessToken}");
Console.WriteLine($"Is OAuth Token Expired ?: {credential.Token.IsExpired(credential.Clock)}");

Console.ReadLine();</pre>
<div id="attachment_5990" style="width: 991px" class="wp-caption aligncenter"><a href="http://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_console_8.jpg" rel="prettyPhoto[gallery-wRCn]"><img class="size-full wp-image-5990" src="http://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_console_8.jpg" alt="Getting an OAuth Token from Google" width="981" height="513" srcset="https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_console_8.jpg 981w, https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_console_8-300x157.jpg 300w, https://blog.falafel.com/wp-content/uploads/2016/12/gcp_oauth_console_8-768x402.jpg 768w" sizes="(max-width: 981px) 100vw, 981px" /></a><p class="wp-caption-text">Getting an OAuth Token from Google</p></div>
<p>Now that we have an OAuth token, we have the ability to call into Pub/Sub related API calls (defined by our scope(s)). Use this token as a Bearer token in the Authorization header of your http calls, as shown below:</p>
</div>
<div>
<pre class="crayon-plain-tag">var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", credential.Token.AccessToken);</pre>
Here is a helper class that encapsulates the functionality that we&#8217;ve just reviewed:<br />
<pre class="crayon-plain-tag">using Google.Apis.Auth.OAuth2;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;

namespace FalafelDev
{
    public class GCP_OAuth_ServiceCredential
    {
        public ServiceCredential Credential { get; }

        public GCP_OAuth_ServiceCredential(string serviceAccountEmail, string p12CertificatePath, List&lt;string&gt; scopes)
        {
            var certificate = new X509Certificate2(p12CertificatePath, "notasecret", X509KeyStorageFlags.Exportable);
            Credential = new ServiceAccountCredential(
                 new ServiceAccountCredential.Initializer(serviceAccountEmail)
                 {
                     Scopes = scopes 
                 }.FromCertificate(certificate));
        }

        public async Task&lt;HttpClient&gt; GetHttpClient()
        {
            bool hasToken = false;

            if (Credential.Token == null || Credential.Token.IsExpired(Credential.Clock))
            {
                hasToken = await Credential.RequestAccessTokenAsync(CancellationToken.None);
            }
            else
            {
                hasToken = true;
            }
            if (hasToken)
            {
                var httpClient = new HttpClient();
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", 
                       Credential.Token.AccessToken);
                httpClient.DefaultRequestHeaders.Accept.Clear();
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                return httpClient;
            }

            return null;

        }
    }
}</pre>
&nbsp;</p>
</div>
<div></div>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/oauth-google-cloud-authentication/">Pub/Sub Part 1 : C# OAuth Authentication to Google Cloud Pub/Sub using a Service Account</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/oauth-google-cloud-authentication/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">5989</post-id>	</item>
		<item>
		<title>Understanding Natural Language</title>
		<link>https://blog.falafel.com/understanding-natural-language/</link>
		<comments>https://blog.falafel.com/understanding-natural-language/#respond</comments>
		<pubDate>Wed, 25 Jan 2017 14:00:11 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[Cloud Platform]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Entity Analysis]]></category>
		<category><![CDATA[Google Cloud]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>
		<category><![CDATA[Natural Language Processing]]></category>
		<category><![CDATA[NLP]]></category>
		<category><![CDATA[Sentiment Analysis]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6017</guid>
		<description><![CDATA[<p>This is post 8 of 17 in the series &#8220;Google Cloud for the .NET Developer&#8221; Isaac Asimov speculated that you could plug a politician&#8217;s speech into a mathematical model, zero out the equation, and prove that the politician had said nothing. We know this intuitively, but I never thought you could actually do it. The Natural Language API from the Google Cloud Platform comes close by measuring sentiment found in text. The Natural Language API sentiment score ranges from –1.0 (negative emotion) to 1.0 (positive emotion). Ever watch HGTV? This may sound familiar: &#8220;The kitchen is so cramped. I really...</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/understanding-natural-language/">Understanding Natural Language</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<aside class="wp-post-series-box series-google-cloud-for-the-net-developer">
	<p class="wp-post-series-name">
		This is post 8 of 17 in the series <em>&ldquo;Google Cloud for the .NET Developer&rdquo;</em>	</p>

	
	</aside>
<p><a href="https://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=2&amp;cad=rja&amp;uact=8&amp;ved=0ahUKEwiomr3OqZXRAhUEyGMKHVCkDToQFggjMAE&amp;url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FIsaac_Asimov&amp;usg=AFQjCNF0s6-eplkucZVRyZXs6Jv0VUp9zA&amp;sig2=Ce_4MkAacavHqBvWKMRmHg">Isaac Asimov</a> speculated that you could plug a politician&#8217;s speech into a mathematical model, zero out the equation, and prove that the politician had said nothing. We know this intuitively, but I never thought you could actually do it. The <a href="https://cloud.google.com/natural-language/">Natural Language API</a> from the Google Cloud Platform comes close by measuring sentiment found in text. The Natural Language API sentiment <em>score</em> ranges from –1.0 (negative emotion) to 1.0 (positive emotion). Ever watch <a href="https://www.youtube.com/user/HGTV">HGTV</a>? This may sound familiar:</p>
<blockquote><p>&#8220;The kitchen is so cramped. I really detest the backsplash and I absolutely hate the cabinets. I&#8217;ve never seen such a poor excuse for a kitchen.&#8221;</p></blockquote>
<p>Emphatically negative. They&#8217;ll have to rip out everything out of their first world kitchen and start over. The flip side is equally strong, but positive:</p>
<blockquote><p>&#8220;The kitchen is the best ever! The spacious layout is perfect and has everything for our needs.&#8221;</p></blockquote>
<p>We&#8217;ll take a look at the three major features of the Natural Language API: <a href="#_Sentiment_Analysis">sentiment analysis</a> to measure feeling and intent, <a href="#_Entities">entity analysis</a> to identify people/places/things mentioned in the text, and <a href="#_Syntax_Analysis">syntactic analysis</a> to describe the underlying linguistic structure of the text.</p>
<h2>Sentiment Analysis</h2>
<p>We&#8217;ll get to the code in a sec, but first <a href="https://cloud.google.com/natural-language/" target="_blank"><span style="color: #669966; text-decoration: underline;">try it here</span></a>.</p>
<p><a href="http://blog.falafel.com/wp-content/uploads/2016/12/122916_0410_Understandi1.png" rel="prettyPhoto[gallery-uA8U]"><img class="alignnone" src="http://blog.falafel.com/wp-content/uploads/2016/12/122916_0410_Understandi1.png" width="624" height="335" border="0" /></a></p>
<p>The scores for each sentence are clearly negative. The <em>magnitude, </em>measured from 0.0 to infinity, indicates strength of feeling. Now once more (with feeling), take a look at this strong positive statement:</p>
<p><a href="http://blog.falafel.com/wp-content/uploads/2016/12/122916_0410_Understandi2.png" rel="prettyPhoto[gallery-uA8U]"><img class="alignnone" src="http://blog.falafel.com/wp-content/uploads/2016/12/122916_0410_Understandi2.png" width="624" height="297" border="0" /></a></p>
<p>The API returns score and magnitude for each sentence and for the entire document. Each magnitude contributes to the document, so longer documents can reach higher magnitudes.</p>
<p>As with many of the Google Cloud API&#8217;s, you can hit the API directly from a REST service or use a C# wrapper. In these examples, I&#8217;m using <a href="https://www.nuget.org/packages/Google.Cloud.Language.V1/">Google.Cloud.Language.V1 package from NuGet</a> to install the C# wrappers. Once installed, you can use the <em>Google.Cloud.Language.V1</em> namespace and its <em>LanguageServiceClient</em> class to access key methods.</p>
<p>The general pattern is to create a <em>LanguageServiceClient</em>, create a Document object for the text, and then call one of the LanguageServiceClient methods: <a href="https://cloud.google.com/natural-language/reference/rest/v1/documents/analyzeSentiment">AnalyzeSentiment()</a>, <a href="https://cloud.google.com/natural-language/reference/rest/v1/documents/analyzeEntities">AnalyzeEntities()</a> or <a href="https://cloud.google.com/natural-language/reference/rest/v1/documents/analyzeSyntax">AnalyzeSyntax().</a> Client methods each return a response object. For example, AnalyzeSentiment returns a <em>Sentences</em> collection in the response. Each sentence has text content, score and magnitude.</p>
<pre class="crayon-plain-tag">var response = client.AnalyzeSentiment(doc);

foreach (var sentence in response.Sentences)
{
    Console.WriteLine(columns,
        sentence.Text.Content,
        sentence.Sentiment.Score,
        sentence.Sentiment.Magnitude);
}</pre>
<p><strong>Note: </strong>You can assign text to the Document <em>Content</em> property directly, or assign the <em>GcsContentUri</em> property to point at storage on the cloud. The Document class lives in the Google.Cloud.Language.V1 namespace.</p>
<pre class="crayon-plain-tag">using Google.Cloud.Language.V1;

const string columns = "{0,-30}{1,10}{2,10}";

var client = LanguageServiceClient.Create();

var doc = new Document()
{
    Content = "The kitchen is the best ever! The layout is perfect.",
    Type = Document.Types.Type.PlainText
};

var response = client.AnalyzeSentiment(doc);

Console.WriteLine(columns, "", "Score", "Magnitude");


foreach (var sentence in response.Sentences)
{
    Console.WriteLine(columns,
        sentence.Text.Content,
        sentence.Sentiment.Score,
        sentence.Sentiment.Magnitude
        );
}

Console.WriteLine(columns,
    "Document Sentiment",
    response.DocumentSentiment.Score,
    response.DocumentSentiment.Magnitude);

}</pre>
<p>The output shows the score and magnitude for each sentence and for the document as a whole.</p>
<p><a href="http://blog.falafel.com/wp-content/uploads/2016/12/122916_0410_Understandi3.png" rel="prettyPhoto[gallery-uA8U]"><img class="alignnone" src="http://blog.falafel.com/wp-content/uploads/2016/12/122916_0410_Understandi3.png" width="624" height="192" border="0" /></a></p>
<p><span style="color: #404040;"><em>Caveat: The API was just released in July 2016, so its early days yet. Sentiment analysis is still vulnerable to misunderstanding, particularly for small amounts of text. &#8220;I&#8217;d really hate to lose the kitchen&#8221; scores a -3 sentiment while &#8220;I&#8217;d really love to lose the kitchen&#8221; is a +4. But the API isn&#8217;t a special purpose one-off. It&#8217;s an outgrowth of Google&#8217;s </em>Machine Learning<em> product, so my expectation is that accuracy will improve.<br />
</em></span></p>
<h2>Entities</h2>
<p><em>AnalyzeEntities()</em> identifies key objects in text: their importance (salience) and their types (e.g. person, organization, location, event…) Each instance of an entity is a <em>Mention</em> that includes its position in the text. The text example is a little longer and has repeated mentions of &#8220;Google&#8221; and &#8220;California&#8221;.</p>
<p>Here&#8217;s the output shown in descending order by salience. This example only lists the entities, but you can rummage through the mentions for each entity as well.</p>
<p><a href="http://blog.falafel.com/wp-content/uploads/2016/12/122916_0410_Understandi4.png" rel="prettyPhoto[gallery-uA8U]"><img class="alignnone" src="http://blog.falafel.com/wp-content/uploads/2016/12/122916_0410_Understandi4.png" width="624" height="351" border="0" /></a></p>
<h2>Syntax Analysis</h2>
<p>To tease meaning from a document, such as sentiment or entities, there&#8217;s grunt work to be done first &#8212; extracting sentences and words, labeling parts of speech, and mapping relationships between words. <a href="https://cloud.google.com/natural-language/reference/rest/v1/documents/analyzeSyntax">AnalyzeSyntax</a> does this fundamental work for you by examining a document and reporting its linguistic makeup.</p>
<p><a href="http://blog.falafel.com/wp-content/uploads/2016/12/122916_0410_Understandi5.png" rel="prettyPhoto[gallery-uA8U]"><img class="alignnone" src="http://blog.falafel.com/wp-content/uploads/2016/12/122916_0410_Understandi5.png" width="624" height="337" border="0" /></a></p>
<p>AnalyzeSyntax extracts an array of <a href="https://cloud.google.com/natural-language/reference/rest/v1/Token">Token</a> where tokens are the words and punctuation that make up a sentence. Each Token has a <a href="https://cloud.google.com/natural-language/reference/rest/v1/TextSpan">TextSpan</a> with its text content and position, <a href="https://cloud.google.com/natural-language/reference/rest/v1/Token">PartOfSpeech</a> to describe its function in the sentence, <a href="https://cloud.google.com/natural-language/reference/rest/v1/Token">DependencyEdge</a> to map the token&#8217;s relationship with other tokens, and <a href="https://en.wikipedia.org/wiki/Lemma_%28morphology%29">lemma</a>. The lemma is a base word that other words are formed from, for example &#8220;run&#8221; is the lemma for &#8220;running&#8221; and &#8220;ran&#8221;.</p>
<p>The PartOfSpeech Types defines a token&#8217;s role in terms of case, gender, mood, tense and so on.</p>
<p><a href="http://blog.falafel.com/wp-content/uploads/2016/12/122916_0410_Understandi6.png" rel="prettyPhoto[gallery-uA8U]"><img class="alignnone" src="http://blog.falafel.com/wp-content/uploads/2016/12/122916_0410_Understandi6.png" width="624" height="365" /></a></p>
<p>Here&#8217;s an example that slices-and-dices the phrase &#8220;It was the best of times, it was the worst of times&#8221;. Reflection + Linq list the parts of speech in a text description. Any parts of speech with the value <em>Unknown</em> are left out.</p>
<pre class="crayon-plain-tag">// create the Document object
// Document is defined in the Google.Cloud.Language.V1 namespace
var doc = new Document()
{
    Content = "It was the best of times, it was the worst of times",
    Type = Document.Types.Type.PlainText
};

// create a client with default settings            
var client = LanguageServiceClient.Create();

// analyze syntax in the doc 
var response = client.AnalyzeSyntax(doc);

// list tokens
var tokens =
    from t in response.Tokens
    let partsOfSpeech = from prop in t.PartOfSpeech
    .GetType()
    .GetProperties(BindingFlags.Public | BindingFlags.Instance)
                        where !prop.GetValue(t.PartOfSpeech).ToString().Equals("Unknown")
                        select prop.Name + "(" + prop.GetValue(t.PartOfSpeech) + ")"
    select new
    {
        Offset = t.Text.BeginOffset.ToString(),
        Text = t.Text.Content,
        Description = string.Join(", ", partsOfSpeech)
    };

// print the list of tokens and descriptions
tokens.ToList().ForEach((token) =&gt;
{
    Console.WriteLine("{0,6} {1, 10} {2,-30}", token.Offset, token.Text, token.Description);
});</pre>
<p>Here&#8217;s the output in the console window:</p>
<p><a href="http://blog.falafel.com/wp-content/uploads/2016/12/122916_0410_Understandi7.png" rel="prettyPhoto[gallery-uA8U]"><img class="alignnone" src="http://blog.falafel.com/wp-content/uploads/2016/12/122916_0410_Understandi7.png" width="624" height="274" /></a></p>
<h2>Where to from here?</h2>
<p>I&#8217;m intrigued by the possibilities of the API, all on its own. But there&#8217;s a natural affinity with related API&#8217;s &#8212; <a href="https://cloud.google.com/bigquery/">BigQuery</a>, <a href="https://cloud.google.com/speech/">Speech</a>, <a href="https://cloud.google.com/vision/">Vision Optical Character Recognition</a>, and <a href="https://cloud.google.com/translate/">Translation</a> – that could generate some really interesting mashups. For example, <a href="https://cloud.google.com/blog/big-data/2016/07/using-the-cloud-natural-language-api-to-analyze-harry-potter-and-the-new-york-times">analyzing top news trends</a>, scanning help desk email for trouble spots, or gauging reaction to social media (without using a star rating UI). I suppose the API could be used to react in real-time to text as its produced, but the real value may be in getting actionable data from the large chunks of unstructured text data found on servers all over the world.</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/understanding-natural-language/">Understanding Natural Language</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/understanding-natural-language/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6017</post-id>	</item>
		<item>
		<title>ConfigSource Your Rewrite Rules</title>
		<link>https://blog.falafel.com/configsource-rewrite-rules/</link>
		<comments>https://blog.falafel.com/configsource-rewrite-rules/#comments</comments>
		<pubDate>Tue, 24 Jan 2017 15:00:29 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Administration]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[web.config]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6189</guid>
		<description><![CDATA[<p>When your Web.Config Gets too Big Maintaining a web.config in your ASP.NET application can quickly get out of hand. It contains the bulk of your web application&#8217;s settings and configurations, and even the fresh, out-of-the-box version is several hundred lines long. If you have a set of IIS URL Rewrite Rules to maintain in the same file, the web.config can become immense. This is where using configsource can come in handy. Benefits of ConfigSource In my view there are some large advantages to separating your list of rewrite rules out from the web.config file into a separate, configsource-appointed config file....</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/configsource-rewrite-rules/">ConfigSource Your Rewrite Rules</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<h2>When your Web.Config Gets too Big</h2>
<p>Maintaining a web.config in your ASP.NET application can quickly get out of hand. It contains the bulk of your web application&#8217;s settings and configurations, and even the fresh, out-of-the-box version is several hundred lines long. If you have a set of IIS URL Rewrite Rules to maintain in the same file, the web.config can become immense. This is where using configsource can come in handy.</p>
<h2>Benefits of ConfigSource</h2>
<p>In my view there are some large advantages to separating your list of rewrite rules out from the web.config file into a separate, configsource-appointed config file. The first is the above-mentioned maintainability of the web.config. Rather than letting the web.config grow in size, doubling depending on the complexity of your rewrite rules, you only add a few lines one time (the configsource instruction) and never have to delve into the web.config again.</p>
<p>The second major advantage is that you no longer have to concern yourself with restarting your web application just because you wish to update a rewrite rule. By default. ASP.NET web applications watch certain files and folders for any changes, and trigger an automatic restart if any of them are touched. The web.config file is one such file. When you have your rewrite rules as a configsource entry instead of being inlined within the web.config, you can change the rules as much as you like without having to restart your application one or more times. And if you do want to restart, you&#8217;re still free to do so anyway. But the choice is now in your hands.</p>
<p>Separation of concerns is another plus to using configsource. The web.config file has a lot of responsibilities and reasons to change as it is (major no-nos when trying to adhere to <a href="https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)">SOLID principles</a>. With configsource, you can have a file whose sole responsibility and reason to change is to maintain IIS rewrite rules, and the web.config can happily pass that responsibility along to the latter.</p>
<h2>Enabling ConfigSource for Rewrite Rules in your Web.Config</h2>
<p>Setting up your web.config to have rewrite rules using configsource is incredibly simple. Take this segment of a web.config that has some rewrite rules in it:</p>
<pre class="crayon-plain-tag">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;configuration&gt;
  &lt;!-- Snip --&gt;
  &lt;system.webServer&gt;
    &lt;!-- Snip --&gt;
    &lt;rewrite&gt;
      &lt;rules&gt;
        &lt;rule name="RemoveTrailingSlashRule1" enabled="false" stopProcessing="true"&gt;
          &lt;match url="(.*)/$" /&gt;
          &lt;conditions logicalGrouping="MatchAll" trackAllCaptures="false"&gt;
            &lt;add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /&gt;
            &lt;add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /&gt;
            &lt;add input="{REQUEST_FILENAME}" pattern="(.*?)\.svc$" negate="true" /&gt;
          &lt;/conditions&gt;
          &lt;action type="Redirect" url="{R:1}" /&gt;
        &lt;/rule&gt;
        &lt;rule name="LowerCaseRule1" enabled="false" stopProcessing="true"&gt;
          &lt;match url="[A-Z]" ignoreCase="false" /&gt;
            &lt;action type="Redirect" url="{ToLower:{URL}}" redirectType="Permanent" /&gt;
        &lt;/rule&gt;
      &lt;/rules&gt;
    &lt;/rewrite&gt;
  &lt;/system.webServer&gt;
  &lt;!-- Snip --&gt;
&lt;/configuration&gt;</pre>
<p>To separate your rules out, leave the  XML within , but remove all of its contents and make it a self-closing tag. Add a &#8220;configSource&#8221; sttribute and specify the name of the file where your rules will live going forward.</p>
<pre class="crayon-plain-tag">&lt;rewrite&gt;
  &lt;rules configSource="rewrite.config" /&gt;
&lt;/rewrite&gt;</pre>
<p>This file will be on the same level as the web.config.</p>
<p><img src="https://blog.falafel.com/wp-content/uploads/2017/01/cover.png" alt="The configsource-appointed rewrite.config file exists on the same level as the web.config file in your file system." /></p>
<p>Within your new config file, simply specify the rules as they would have been in the web.config originally. The following sample is the entire contents of the new rewrite.config file.</p>
<pre class="crayon-plain-tag">&lt;rules&gt;
  &lt;rule name="RemoveTrailingSlashRule1" enabled="false" stopProcessing="true"&gt;
    &lt;match url="(.*)/$" /&gt;
    &lt;conditions logicalGrouping="MatchAll" trackAllCaptures="false"&gt;
      &lt;add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /&gt;
      &lt;add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /&gt;
      &lt;add input="{REQUEST_FILENAME}" pattern="(.*?)\.svc$" negate="true" /&gt;
    &lt;/conditions&gt;
    &lt;action type="Redirect" url="{R:1}" /&gt;
  &lt;/rule&gt;
  &lt;rule name="LowerCaseRule1" enabled="false" stopProcessing="true"&gt;
    &lt;match url="[A-Z]" ignoreCase="false" /&gt;
      &lt;action type="Redirect" url="{ToLower:{URL}}" redirectType="Permanent" /&gt;
  &lt;/rule&gt;
&lt;/rules&gt;</pre>
<p>Now you have a nice separation of concerns setup, and are no longer beholden to having to edit the web.config file whenever an IIS rewrite rule needs added, modified, or removed.</p>
<h2>ConfigSource for Other Web.Config Elements</h2>
<p>As a brief mention, the rewrite rules section of the web.config is not the only one you can use configsource with! Many, many other sections in the web.config support this feature, and you can read more about configsource in general at <a href="http://msdn.microsoft.com/en-US/library/system.configuration.sectioninformation.configsource(v=vs.100).aspx">Microsoft&#8217;s documentation page</a>.</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/configsource-rewrite-rules/">ConfigSource Your Rewrite Rules</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/configsource-rewrite-rules/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6189</post-id>	</item>
		<item>
		<title>Porting Azure Web Apps to Google Cloud Platform (GCP)</title>
		<link>https://blog.falafel.com/porting-azure-web-apps-to-google-cloud-platform/</link>
		<comments>https://blog.falafel.com/porting-azure-web-apps-to-google-cloud-platform/#respond</comments>
		<pubDate>Tue, 24 Jan 2017 14:00:53 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[Cloud Platform]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6091</guid>
		<description><![CDATA[<p>This is post 7 of 17 in the series &#8220;Google Cloud for the .NET Developer&#8221; Introduction So you&#8217;ve decided to port your ASP.NET 4.x Azure Web Apps to the Google Cloud Platform (GCP). The only option available today for hosting non-Core ASP.NET in GCP is with Windows Server VMs in Compute Engine. Let&#8217;s start by acknowledging that this is a move from a Platform as a Service (PaaS) to Infrastructure as a Service (IaaS), with all the typical tradeoffs: in short, you sacrifice rich features in exchange for increased granularity of control. With that in mind, let&#8217;s take a look...</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/porting-azure-web-apps-to-google-cloud-platform/">Porting Azure Web Apps to Google Cloud Platform (GCP)</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<aside class="wp-post-series-box series-google-cloud-for-the-net-developer">
	<p class="wp-post-series-name">
		This is post 7 of 17 in the series <em>&ldquo;Google Cloud for the .NET Developer&rdquo;</em>	</p>

	
	</aside>
<h1>Introduction</h1>
<p>So you&#8217;ve decided to port your ASP.NET 4.x Azure Web Apps to the Google Cloud Platform (GCP). The only option available today for hosting non-Core ASP.NET in GCP is with Windows Server VMs in Compute Engine. Let&#8217;s start by acknowledging that this is a move from a Platform as a Service (PaaS) to Infrastructure as a Service (IaaS), with all the typical tradeoffs: in short, you sacrifice rich features in exchange for increased granularity of control. With that in mind, let&#8217;s take a look at some of the most fundamental tasks in deploying and managing a cloud-based app: publishing to a cloud testing environment and then deploying a production version to a load-balanced, auto-scaling cluster.</p>
<h1>Publishing an ASP.NET Web App to a Windows Server VM in GCP</h1>
<p>In another topic, I talked through the steps to take to create a new Windows Server VM ready to run ASP.NET applications in GCP. By the end of those steps, you should have created a Windows user account and gotten back a random password. You now have everything you need to publish an ASP.NET application to the Windows Server VM, straight from Visual Studio. Select your web app, then select Build | Publish&#8230; to open the Publish dialog. Under &#8220;Select a publish target&#8221;, choose Custom. Fill in the Server and Destination URL using the Site address in the Deployment Manager.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-site-address.png" rel="prettyPhoto[gallery-prC8]"><img class="aligncenter size-full wp-image-6095" src="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-site-address.png" alt="" width="345" height="168" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-site-address.png 345w, https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-site-address-300x146.png 300w" sizes="(max-width: 345px) 100vw, 345px" /></a></p>
<p>And fill in the User name and Password with the Windows user you created and the password generated by GCP. Fresh out of the box, IIS is configured with a single web site named &#8220;Default Web Site&#8221;. Use that as the Site name.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-Publish-dialog-redacted.png" rel="prettyPhoto[gallery-prC8]"><img class="aligncenter size-full wp-image-6096" src="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-Publish-dialog-redacted.png" alt="" width="706" height="558" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-Publish-dialog-redacted.png 706w, https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-Publish-dialog-redacted-300x237.png 300w" sizes="(max-width: 706px) 100vw, 706px" /></a></p>
<p>And that&#8217;s it! Click Publish, and Visual Studio will build and publish the web app to IIS on the VM. After publishing, your default browser will automatically open the Destination URL.</p>
<h2>Common additional steps</h2>
<h3>Enable SSL</h3>
<p>Most web sites and applications these days support SSL or even insist upon it. You will have to take a few extra steps to enable this in your Windows Server VM. If you already know your way around IIS, then you know how to do this. However, if you&#8217;re coming from Azure, you might not. Here&#8217;s a quick visual guide.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-SSL-binding.png" rel="prettyPhoto[gallery-prC8]"><img class="aligncenter size-full wp-image-6097" src="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-SSL-binding.png" alt="" width="708" height="645" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-SSL-binding.png 708w, https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-SSL-binding-300x273.png 300w" sizes="(max-width: 708px) 100vw, 708px" /></a></p>
<ol>
<li>In the Site Actions menu, click Bindings&#8230;</li>
<li>In the Site Bindings dialog, click Add&#8230;</li>
<li>In the Add Site Binding dialog, set the Type to &#8220;https&#8221;</li>
<li>Select an SSL certificate. GCP Windows Server instances come with a self-signed certificate that you can use for development, but for production you&#8217;ll want to purchase a certificate signed by a widely recognized Certificate Authority (CA).</li>
</ol>
<h3>Enable URL Rewriting</h3>
<p>Another common scenario that goes hand-in-hand with enabling SSL is forcing SSL by using URL Rewriting. This is enabled by default in Azure, but not in IIS. In fact, if you have an app that includes URL Rewriting in web.config, your app will simply not work until you enable this feature in IIS. The error you&#8217;ll see will simply state &#8220;HTTP Error 500.19 &#8212; Internal Server Error. The requested page cannot be accessed because the related configuration data for the page is invalid.&#8221; The easiest way to enable it is to use the Web Platform Installer to search for &#8220;URL Rewrite&#8221; and install it.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-URL-Rewrite.png" rel="prettyPhoto[gallery-prC8]"><img class="aligncenter wp-image-6099 size-full" src="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-URL-Rewrite.png" width="794" height="377" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-URL-Rewrite.png 794w, https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-URL-Rewrite-300x142.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-URL-Rewrite-768x365.png 768w" sizes="(max-width: 794px) 100vw, 794px" /></a></p>
<p>Of course, lacking the URL Rewrite module is not the only cause of a 500.19 error. Other configuration-related errors including malformed or invalid XML may also result in this error.</p>
<h1>Preparing for Horizontal Scaling</h1>
<p>To me, deploying to a single instance in the cloud for testing fills a pretty similar role to having a staging slot in Azure. It&#8217;s probably OK that the staging environment is a single instance, but in production you&#8217;re probably going to want so scale on demand or even automatically. Let&#8217;s take a look at the steps needed to create an auto-scaling, load-balanced cluster from that staged web app. There&#8217;s already a <a href="https://cloud.google.com/dotnet/docs/getting-started/using-instance-groups" target="_blank">great walkthrough</a> in the GCP dotnet docs. Don&#8217;t be intimidated; in spite of the length, it is not a complicated process&#8211;merely a multi-step one.</p>
<p>I stepped through the walkthrough myself, but rather than using the bookshelf sample app, I wanted to deploy a super-simple app that just reported the IP address of the host that handled the request so I could see for myself that requests were being distributed across instance group members. Whenever the walkthrough said to enable API access, I skipped those, because my app didn&#8217;t use any GCP APIs. I also chose &#8220;None&#8221; for Session affinity to get a round-robin distribution, to more easily observe that traffic was going to the 2 instances I requested for the group I created. Once it was all set up, I could see my VM instances created by the instance group.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-group-instances.png" rel="prettyPhoto[gallery-prC8]"><img class="aligncenter size-full wp-image-6100" src="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-group-instances.png" alt="" width="1060" height="240" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-group-instances.png 1060w, https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-group-instances-300x68.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-group-instances-768x174.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-group-instances-1024x232.png 1024w" sizes="(max-width: 1060px) 100vw, 1060px" /></a></p>
<p>And navigating to the IP address of the load balancer resulted in a page that reported back one of the two internal IP addresses.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-HostInfoModel.png" rel="prettyPhoto[gallery-prC8]"><img class="aligncenter size-full wp-image-6101" src="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-HostInfoModel.png" alt="" width="211" height="204" /></a></p>
<p>According to the documentation, traffic will continue to be routed to the same host for the duration of the session. I was able to confirm this by refreshing the page and observing that the address did not change. Then I navigated to the load balancer&#8217;s IP address in an incognito window and got back the other instance&#8217;s IP address.</p>
<p>Scaling an ASP.NET web app&#8211;or any other app in VMs&#8211;is currently a manual multi-step process that can&#8217;t be fully automated due to the need to RDP into the target VM to run GCESysPrep. There is also currently not a really good story for rolling out updates to instance groups yet; the <a href="https://cloud.google.com/compute/docs/instance-groups/updating-managed-instance-groups" target="_blank">Instance Group Updater</a> service is currently in alpha. I hope to see it become ready for production use soon!</p>
<h1>Conclusion</h1>
<p>As you may have noticed, while it is possible to migrate an ASP.NET 4.x web app from Azure to GCP VMs, it comes at the cost of some conveniences that you may have taken for granted in Azure. This is obviously a bit of an unfair comparison since the same could be said about Azure Web Apps vs Azure VMs. A closer comparison would be moving an ASP.NET Core Web App from Azure to GCP App Engine Flex, but that&#8217;s better left as the topic of another post.</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/porting-azure-web-apps-to-google-cloud-platform/">Porting Azure Web Apps to Google Cloud Platform (GCP)</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/porting-azure-web-apps-to-google-cloud-platform/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6091</post-id>	</item>
		<item>
		<title>Google Cloud Platform (GCP) Compute Engine &#8211; Windows Server VMs</title>
		<link>https://blog.falafel.com/google-cloud-platform-compute-engine-windows-server-vms/</link>
		<comments>https://blog.falafel.com/google-cloud-platform-compute-engine-windows-server-vms/#respond</comments>
		<pubDate>Mon, 23 Jan 2017 14:00:12 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[Cloud Platform]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[GCP]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6041</guid>
		<description><![CDATA[<p>This is post 6 of 17 in the series &#8220;Google Cloud for the .NET Developer&#8221; Intro to GCP Compute Engine If you&#8217;re a Windows .NET developer, then when you think cloud, your first thought is probably Microsoft Azure. However, Google Cloud Platform (GCP) has a very strong offering for Windows developers as well, starting with one of the most fundamental building blocks of cloud computing: the Virtual Machine (VM). The Google Cloud Platform&#8217;s name for VMs in the cloud is Compute Engine. It might be intimidating to step into an arena largely populated by unfamiliar Linux servers and enough foreign...</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/google-cloud-platform-compute-engine-windows-server-vms/">Google Cloud Platform (GCP) Compute Engine &#8211; Windows Server VMs</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<aside class="wp-post-series-box series-google-cloud-for-the-net-developer">
	<p class="wp-post-series-name">
		This is post 6 of 17 in the series <em>&ldquo;Google Cloud for the .NET Developer&rdquo;</em>	</p>

	
	</aside>
<h1>Intro to GCP Compute Engine</h1>
<p>If you&#8217;re a Windows .NET developer, then when you think cloud, your first thought is probably Microsoft Azure. However, Google Cloud Platform (GCP) has a very strong offering for Windows developers as well, starting with one of the most fundamental building blocks of cloud computing: the Virtual Machine (VM). The Google Cloud Platform&#8217;s name for VMs in the cloud is <a href="https://cloud.google.com/compute/" target="_blank">Compute Engine</a>. It might be intimidating to step into an arena largely populated by unfamiliar Linux servers and enough foreign programming languages to populate a veritable Tower of Babel, but let me reassure you: working with Windows Server VMs in GCP is extremely friendly and approachable. In this tour, I&#8217;ll act as your friendly guide to show you some of the things that I like and appreciate about the VM management experience in GCP. Just so you know where I&#8217;m coming from: I&#8217;m happier and more comfortable writing code than wrangling infrastructure, so if I can find things to love about managing VMs in GCP, then I bet you can too.</p>
<h1>Creating Windows Server VMs</h1>
<p>There are two main ways to create a new VM in GCP: by creating a new instance from the Compute Engine | VM Instances tab, or by using the Cloud Launcher. The difference here is that the Cloud Launcher offers a catalog of preconfigured VM images with additional software installed, whereas creating a new VM instance in the Compute Engine tab will get you a VM with nothing more than the selected OS installed.</p>
<h2>Creating an Empty VM</h2>
<p>For ASP.NET development, it will generally be more convenient to use the Cloud Launcher to take advantage of the pre-configured images, but let&#8217;s take a quick look at creating a plain VM first.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-Create-Instance.png" rel="prettyPhoto[gallery-08Ph]"><img class="aligncenter size-full wp-image-6044" src="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-Create-Instance.png" alt="" width="839" height="366" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-Create-Instance.png 839w, https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-Create-Instance-300x131.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-Create-Instance-768x335.png 768w" sizes="(max-width: 839px) 100vw, 839px" /></a></p>
<p>Here you can see the basic options available. The machine type dropdown actually controls both vCPU and memory in lockstep, but you can create custom combinations of CPU and memory if you desire. Below that is the boot disk configuration where you choose operating system, disk type (standard or SSD) and disk size. Finally, to the right is a terrific itemized breakdown of the cost, so you can quickly and interactively see how the options you choose affect the price. Lastly, I want to call attention to this little nugget at the bottom because it&#8217;s easy to miss and yet so appreciated.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-Create-Instance-Equivalents.png" rel="prettyPhoto[gallery-08Ph]"><img class="aligncenter size-full wp-image-6045" src="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-Create-Instance-Equivalents.png" alt="" width="198" height="74" /></a></p>
<p>After you interactively configure a VM, you can click these links to get a modal window that contains the exact REST or gcloud command so you can automate creation of identical VMs in the future. You&#8217;ll find thoughtful little concessions like this sprinkled throughout the GCP UI.</p>
<p>At this point you can click Create to provision a brand-new Windows Server with nothing installed.</p>
<h2>Creating an ASP.NET VM with Cloud Launcher</h2>
<p>Now let&#8217;s take a look at what you get by using the Cloud Launcher to create an ASP.NET VM. Cloud Launcher will both create a VM with the configuration you specify, and also customize that VM with additional software and configurations. Right now, you can find the image in the Cloud Launcher just by searching for &#8220;asp&#8221;.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Cloud-Launcher-asp-search.png" rel="prettyPhoto[gallery-08Ph]"><img class="aligncenter size-full wp-image-6047" src="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Cloud-Launcher-asp-search.png" alt="" width="402" height="638" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Cloud-Launcher-asp-search.png 402w, https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Cloud-Launcher-asp-search-189x300.png 189w" sizes="(max-width: 402px) 100vw, 402px" /></a></p>
<p>As you can see in the text on the card, this image includes IIS and ASP.NET. The inclusion of SQL Express is simply to make it easy to get started with ASP.NET in GCP, because obviously you can&#8217;t and won&#8217;t scale an app without a common database&#8211;at least in most cases. Clicking on the card will bring up a more complete set of information including a pricing projection based on the default configuration. Unfortunately, if you choose to customize the image before creation, you won&#8217;t get to see an updated pricing projection like you can with the Compute Engine UI. I&#8217;ll create one with the default configuration so you can see how to manage one of these VMs.</p>
<h1>Managing Windows VMs in the Google Cloud</h1>
<p>Whether you create a bare Windows Server instance or use the Cloud Launcher, you will end up in the Deployment Manager. On the right side of the page, just under the instance info, there is a button with a dropdown button on it.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-set-password.png" rel="prettyPhoto[gallery-08Ph]"><img class="aligncenter size-full wp-image-6048" src="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-set-password.png" alt="" width="368" height="175" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-set-password.png 368w, https://blog.falafel.com/wp-content/uploads/2017/01/GCP-Compute-Engine-set-password-300x143.png 300w" sizes="(max-width: 368px) 100vw, 368px" /></a></p>
<p>Available options are:</p>
<ul>
<li>RDP</li>
<li>Create/reset password</li>
<li>Show gcloud command to reset password</li>
<li>Download RDP file</li>
</ul>
<p>The first thing you should do is actually create a Windows password. See how once again the UI shows you how to automate this task? I love that! Once you create a Windows password, you can manage the instance remotely. The two main options available are &#8220;RDP&#8221; and &#8220;Download the RDP file&#8221;. The first option will launch a browser-based RDP session, while the second will download a file that contains all the info you need to connect with your local, native RDP client. This is not the only place where a browser-based alternative is available; every GCP account can also launch a browser-based terminal session with a Linux-based environment with many essential developer tools pre-installed and a persistent home directory. You could in theory do all your work on a Chromebook! I mean, you probably wouldn&#8217;t, but it&#8217;s still nice.</p>
<p>Once you&#8217;re at the point where you can connect with RDP to the VM, it&#8217;s just like managing any other Windows Server. I&#8217;ll write separately about my experience migrating an ASP.NET web application from Azure App Services to a VM in GCP.</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/google-cloud-platform-compute-engine-windows-server-vms/">Google Cloud Platform (GCP) Compute Engine &#8211; Windows Server VMs</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/google-cloud-platform-compute-engine-windows-server-vms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6041</post-id>	</item>
		<item>
		<title>Authenticating Your C# Application for the Google Cloud Platform – Part 2</title>
		<link>https://blog.falafel.com/authenticating-your-c-application-for-the-google-cloud-platform-part-2/</link>
		<comments>https://blog.falafel.com/authenticating-your-c-application-for-the-google-cloud-platform-part-2/#respond</comments>
		<pubDate>Fri, 20 Jan 2017 17:00:10 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[Cloud Platform]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Authentication]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6179</guid>
		<description><![CDATA[<p>This is post 5 of 17 in the series &#8220;Google Cloud for the .NET Developer&#8221; Now that we understand how to authenticate a C# application to work with your own project’s GCP resources, let’s take it a step further. In this post, we’ll look at how we can combine that connectivity with end user data, via three-legged OAUTH authorization, to perform operations on user content, with their permission of course. For this example, I’ve created a very simple ASP.NET MVC project that logs a user in, gets their profile image, and uploads it to a specific bucket. Let’s take a...</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/authenticating-your-c-application-for-the-google-cloud-platform-part-2/">Authenticating Your C# Application for the Google Cloud Platform – Part 2</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<aside class="wp-post-series-box series-google-cloud-for-the-net-developer">
	<p class="wp-post-series-name">
		This is post 5 of 17 in the series <em>&ldquo;Google Cloud for the .NET Developer&rdquo;</em>	</p>

	
	</aside>
<p>Now that we understand how to authenticate a C# application to work with your own project’s GCP resources, let’s take it a step further. In this post, we’ll look at how we can combine that connectivity with end user data, via three-legged OAUTH authorization, to perform operations on user content, with their permission of course.</p>
<p>For this example, I’ve created a very simple ASP.NET MVC project that logs a user in, gets their profile image, and uploads it to a specific bucket. Let’s take a closer look at each part.</p>
<h2>Creating API Credentials</h2>
<p>Before we can ask a user for permission, we have to first configure our application with a Client ID and Secret so that we have the necessary elements to complete the OAUTH workflow. This is done by visiting the API Console and creating a new OAUTH Client ID:</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-OAUTH-Client-ID.png" rel="prettyPhoto[gallery-W99U]"><img class="alignnone size-medium wp-image-6180" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-OAUTH-Client-ID-300x266.png" alt="Google-Cloud-Platform-Create-OAUTH-Client-ID" width="300" height="266" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-OAUTH-Client-ID-300x266.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-OAUTH-Client-ID-768x681.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-OAUTH-Client-ID.png 790w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>If you haven’t already configured your OAUTH consent screen, you’ll be prompted to do so. This is required because the authorization request needs to show the user the name of your application, so that it’s clear that you are the one asking for permission:</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-OAUTH-Consent-Screen.png" rel="prettyPhoto[gallery-W99U]"><img class="alignnone size-medium wp-image-6181" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-OAUTH-Consent-Screen-182x300.png" alt="Google-Cloud-Platform-OAUTH-Consent-Screen" width="182" height="300" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-OAUTH-Consent-Screen-182x300.png 182w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-OAUTH-Consent-Screen-622x1024.png 622w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-OAUTH-Consent-Screen.png 664w" sizes="(max-width: 182px) 100vw, 182px" /></a></p>
<p>Now you can proceed to configure the new key, in this case for a Web Application. You need to specify a valid path (within your website) to receive the callback redirect URI to send the user after they grant permission:</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-OAUTH-Client-ID-Credentials.png" rel="prettyPhoto[gallery-W99U]"><img class="alignnone size-medium wp-image-6182" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-OAUTH-Client-ID-Credentials-282x300.png" alt="Google-Cloud-Platform-Create-OAUTH-Client-ID-Credentials" width="282" height="300" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-OAUTH-Client-ID-Credentials-282x300.png 282w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-OAUTH-Client-ID-Credentials-768x818.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-OAUTH-Client-ID-Credentials-962x1024.png 962w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-OAUTH-Client-ID-Credentials.png 1095w" sizes="(max-width: 282px) 100vw, 282px" /></a></p>
<p>For our application, this is represented by the path: <strong>http://localhost:4078/Login/Callback</strong>.</p>
<p>After a user authorizes our app to access their account, Google will redirect them back to this path to complete the OAUTH workflow, sending with it a code that we need to validate the request (more on this later).</p>
<p>Once this is configured, you’ll be given a Client ID and Secret that you’ll need to safely store where it’s accessible only by your site (and not checked into source control or otherwise published!).</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Client-ID-and-Secret.png" rel="prettyPhoto[gallery-W99U]"><img class="alignnone size-medium wp-image-6183" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Client-ID-and-Secret-300x146.png" alt="Google-Cloud-Platform-Client-ID-and-Secret" width="300" height="146" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Client-ID-and-Secret-300x146.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Client-ID-and-Secret-768x374.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Client-ID-and-Secret.png 953w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>To keep things simple we’ll embed them in our code, but you’ll definitely want to protect this on a production site.</p>
<h2>Authenticating the User</h2>
<p>Now that our application is configured to properly request for access, we need to go ahead and create a way to initialize the OAUTH workflow for our users.</p>
<p>I added a simple LoginController that takes care of asking the user to authorize our application to access their account. This controller simply constructs the authorization URL on the trusted Google domain that the user will use to login and authorize the app.</p>
<p>Here’s what the code looks like for the Login Controller with this default action to start the authentication process:</p>
<pre class="crayon-plain-tag">public class LoginController : Controller
    {
        // CLIENT ID AND SECRETSHOULD NOT BE STORED IN CODE OR CONFIG, use Default Credentials or other safe method
        private const string CLIENT_ID = "[CLIENT-ID-KEY-FROM-API-MANAGER]";
        private const string CLIENT_SECRET = "[CLIENT-SECRET-KEY-FROM-API-MANAGER";

        // the bucket we're using to store images
        private const string BUCKET_NAME = "falafel-test-profile-images";

        public ActionResult Index()
        {
            // Build the login oauth url
            var scopes = "email profile";                               // what we want to access
            var redirectUrl = "http://localhost:4078/Login/Callback";   // the url to which Google should send the user back to complete authentication
            var clientID = CLIENT_ID;                                   // SHOULD BE IN A SAFE PLACE, NOT HERE!

            // redirect user to the login url
            var oauthUrl = string.Format("https://accounts.google.com/o/oauth2/v2/auth?scope={0}&amp;redirect_uri={1}&amp;response_type=code&amp;client_id={2}", scopes, redirectUrl, clientID);
            return Redirect(oauthUrl);
        }
    }</pre>
<p>When the user visits this page, they’ll be redirected to the constructed url, which will proceed to ask them to login and authorize your application (using the name you configured on the consent screen):</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Authorize-User-Account.png" rel="prettyPhoto[gallery-W99U]"><img class="alignnone size-medium wp-image-6184" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Authorize-User-Account-300x234.png" alt="Google-Cloud-Platform-Authorize-User-Account" width="300" height="234" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Authorize-User-Account-300x234.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Authorize-User-Account-768x600.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Authorize-User-Account.png 800w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Once they grant access, Google will redirect them back to your site via the Callback URI that you configured when setting up the API credentials. It’s our job to take that code and validate it by posting it (along with our app Secret and other parameters that validate the code) to another Google endpoint.</p>
<p>Here’s the code for the Callback action that handles this request:</p>
<pre class="crayon-plain-tag">public async Task&lt;ActionResult&gt; Callback(string code)
        {
            // build the request to validate the incoming code
            var clientID = CLIENT_ID;                                   // from the Google API console, SHOULD BE IN A SAFE PLACE, NOT HERE!
            var clientSecret = CLIENT_SECRET;                           // from the Google API console, SHOULD BE IN A SAFE PLACE, NOT HERE!
            var redirectUri = "http://localhost:4078/Login/Callback";   // the original url we sent must match what we original set as the callback
            var grantType = "authorization_code";                       // this tells OAUTH we're using a code to validate


            // wrap parameters in a Form object
            var content = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair&lt;string, string&gt;("code", code),   // the code we got from the callback
                new KeyValuePair&lt;string, string&gt;("client_id", clientID),
                new KeyValuePair&lt;string, string&gt;("client_secret", clientSecret),
                new KeyValuePair&lt;string, string&gt;("redirect_uri", redirectUri),
                new KeyValuePair&lt;string, string&gt;("grant_type", grantType),
            });

            // the url to send the POST request (from the google docs)
            var postUrl = "https://www.googleapis.com/oauth2/v4/token";

            // submit the request
            var client = new HttpClient();
            var result = await client.PostAsync(postUrl, content);

            // get the result as a string
            var resultContent = await result.Content.ReadAsStringAsync();

            // parse the result into an object
            var resultObject = new { access_token = "" };
            var json = JsonConvert.DeserializeAnonymousType(resultContent, resultObject);

            // use the token to get the user's profile
            var url = "https://www.googleapis.com/oauth2/v1/userinfo";
            client.DefaultRequestHeaders.Add("Authorization", "Bearer " + json.access_token);
            var response = await client.GetStringAsync(url);

            // parse the new result to get the profile
            var profileResultObject = new { picture = "", id = "" };
            var profileJson = JsonConvert.DeserializeAnonymousType(response, profileResultObject);

            // upload the image to the storage bucket
            await UploadProfileImage(profileJson.picture, profileJson.id);

            // redirect to a result page
            return RedirectToAction("Images", "Home");
        }</pre>
<p>Once we have the user’s permission (via the <strong>access_token</strong> property) we can use that to get their profile information, including their profile image. We use the Google Cloud C# API (authorizing as we described in the previous topic) to upload that profile (via a Stream object) directly to our storage buckets.</p>
<p>This is the code for the <strong>UploadProfileImage</strong> method that performs the upload to Google storage:</p>
<pre class="crayon-plain-tag">private async Task UploadProfileImage(string url, string id)
        {
            // get the keyfile
            var path = Server.MapPath("~/Falafel Test Project-b53a21babe66.json");

            // authorize a client
            var credential = GoogleCredential.FromStream(new FileStream(path, FileMode.Open)).CreateScoped(new string[] { StorageService.Scope.DevstorageReadWrite });
            var storageClient = StorageClient.Create(credential);

            // set the destination bucket, file name and content type
            var destination = new Google.Apis.Storage.v1.Data.Object();
            destination.Bucket = BUCKET_NAME;
            destination.ContentType = "image/jpeg";
            destination.Name = id + ".jpg";
            
            // get the image stream
            var httpClient = new HttpClient();
            var resultStream = await httpClient.GetStreamAsync(url);

            // upload the stream to the destination bucket as public
            storageClient.UploadObject(destination, resultStream, new UploadObjectOptions() { PredefinedAcl = PredefinedObjectAcl.PublicRead });
        }</pre>
<p>Finally, we redirect the user to new action on the Home controller that uses the same authentication to read the images uploaded to the bucket and show them to the user. Here is the code:</p>
<pre class="crayon-plain-tag">public ActionResult Images()
        {

            // the bucket we're using to store images
            var BUCKET_NAME = "falafel-test-profile-images";

            // get the keyfile
            var path = Server.MapPath("~/Falafel Test Project-b53a21babe66.json");

            // authorize a client
            var credential = GoogleCredential.FromStream(new FileStream(path, FileMode.Open)).CreateScoped(new string[] { StorageService.Scope.DevstorageReadOnly });
            var storageClient = StorageClient.Create(credential);

            PagedEnumerable&lt;Objects, Google.Apis.Storage.v1.Data.Object&gt; images = storageClient.ListObjects(BUCKET_NAME);

            return View(images);
        }</pre>
<p>And here is what the resulting page looks like after our first user logs in:</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Profile-Image-Result.png" rel="prettyPhoto[gallery-W99U]"><img class="alignnone size-medium wp-image-6185" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Profile-Image-Result-249x300.png" alt="Google-Cloud-Platform-Profile-Image-Result" width="249" height="300" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Profile-Image-Result-249x300.png 249w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Profile-Image-Result.png 706w" sizes="(max-width: 249px) 100vw, 249px" /></a></p>
<h2>Caveats and Wrapping Up</h2>
<p>Of course, since this is a very simple example, we haven’t done any error checking (such as if the user has already uploaded their image), nor do we do any file locking to ensure multiple people aren’t attempting to read the key file (the result of which should probably be cached) which would probably cause an exception. If you were deploying this to a GCE or GAE instance, you could probably leverage the Default Application Credentials (from the previous topic) to authorize access to your storage account (which is certainly the recommended option)!</p>
<p>Finally, of course, we are embedding the Client ID and Secrets right inside our code, which is certainly a security risk and should never be done on a production site.</p>
<p>However, this hopefully shows how easy it is to authenticate a custom ASP.NET website to use both GCP services as well as client user accounts together to create a solution entirely driven by Google APIs.</p>
<p>A more thorough look at Google Storage and other Google services is coming soon, so stay tuned for more. In the meantime, as always, I hope this was helpful, and thanks for reading!</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/authenticating-your-c-application-for-the-google-cloud-platform-part-2/">Authenticating Your C# Application for the Google Cloud Platform – Part 2</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/authenticating-your-c-application-for-the-google-cloud-platform-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6179</post-id>	</item>
		<item>
		<title>Authenticating Your C# Application for the Google Cloud Platform – Part 1</title>
		<link>https://blog.falafel.com/authenticating-your-c-application-for-the-google-cloud-platform-part-1/</link>
		<comments>https://blog.falafel.com/authenticating-your-c-application-for-the-google-cloud-platform-part-1/#comments</comments>
		<pubDate>Thu, 19 Jan 2017 17:00:26 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[Cloud Platform]]></category>
		<category><![CDATA[Authentication]]></category>
		<category><![CDATA[Authorization]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6138</guid>
		<description><![CDATA[<p>This is post 4 of 17 in the series &#8220;Google Cloud for the .NET Developer&#8221; The new C# libraries for the Google Cloud Platform, available on NuGet, make it easy to get started adding these features to your platform. However, before you can use them, you obviously need to authenticate your application for access. Google uses OAUTH 2.0 as the protocol for authentication In this post we’ll discuss the different scenarios you may encounter, and the different options available for authorizing your application. Server to Server Authentication If you are building an application that is leveraging GCP infrastructure as its...</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/authenticating-your-c-application-for-the-google-cloud-platform-part-1/">Authenticating Your C# Application for the Google Cloud Platform – Part 1</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<aside class="wp-post-series-box series-google-cloud-for-the-net-developer">
	<p class="wp-post-series-name">
		This is post 4 of 17 in the series <em>&ldquo;Google Cloud for the .NET Developer&rdquo;</em>	</p>

	
	</aside>
<p>The new C# libraries for the Google Cloud Platform, available on NuGet, make it easy to get started adding these features to your platform. However, before you can use them, you obviously need to authenticate your application for access.</p>
<p>Google uses OAUTH 2.0 as the protocol for authentication In this post we’ll discuss the different scenarios you may encounter, and the different options available for authorizing your application.</p>
<h2>Server to Server Authentication</h2>
<p>If you are building an application that is leveraging GCP infrastructure as its platform, you only need to authorize your application to your own Google project. For example, you may be building an app that stores data in a Google Cloud Storage, owned by you, setup for your own application.</p>
<h3>Sample Project</h3>
<p>To demonstrate this, I’ve created a very simple project that reads the list of buckets in a Google Storage account and writes them to the console. Here’s the code which uses the StorageClient API:</p>
<pre class="crayon-plain-tag">class Program
    {
        private const string PROJECT_ID = "falafel-test-project";

        static void Main(string[] args)
        {

            try
            {
                var client = StorageClient.Create();
                var buckets = client.ListBuckets(PROJECT_ID);
                foreach (var bucket in buckets)
                {
                    Console.WriteLine(bucket.Name);
                }
                
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

            Console.ReadLine();
        }
    }</pre>
<p>Note the Project ID property, which you can retrieve from your project dashboard:</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Project-Id.png" rel="prettyPhoto[gallery-aJAx]"><img class="alignnone size-medium wp-image-6139" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Project-Id-300x127.png" alt="Google Cloud Platform Project Id" width="300" height="127" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Project-Id-300x127.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Project-Id-768x326.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Project-Id-1024x435.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Project-Id.png 1032w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Of course, if we run this code now, without authorizing it first, we’ll get an error like this:</p>
<blockquote class="error"><p>System.InvalidOperationException: The Application Default Credentials are not available. They are available if running in Google Compute Engine. Otherwise, the environment variable GOOGLE_APPLICATION_CREDENTIALS must be defined pointing to a file defining the credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information.</p></blockquote>
<p>To fix this, we need to first authorize our application. The recommended (and simplest) option to achieve this is to leverage Google Default Application Credentials.</p>
<h3>Google Application Default Credentials</h3>
<p>The preferred method for authentication your application is to leverage the <a href="https://developers.google.com/identity/protocols/application-default-credentials">Google Application Default Credentials</a> via the <strong>gcloud</strong> utility, which is part of the <a href="https://cloud.google.com/sdk">Google Cloud SDK</a>. Be sure that you have already <a href="https://cloud.google.com/sdk/downloads">installed the SDK on your machine</a> before proceeding.</p>
<h4>Beta Tools</h4>
<p>As of the writing of this entry, the command to configure the Google Application Default Credentials are <a href="https://cloud.google.com/sdk/gcloud/reference/beta/">still in beta</a>. Be sure to check that option during installation of the SDK to ensure the command is available:</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Beta-Tools.png" rel="prettyPhoto[gallery-aJAx]"><img class="alignnone size-medium wp-image-6175" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Beta-Tools-300x247.png" alt="Google-Cloud-Platform-Beta-Tools" width="300" height="247" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Beta-Tools-300x247.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Beta-Tools-768x631.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Beta-Tools.png 830w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Alternatively, if you installed the SDK without this option, you can manually add the beta tools by running this command via the SDK:</p>
<pre class="crayon-plain-tag">gcloud components install beta</pre>
<p><em>Note: If you have issues, try running the command as an Administrator.</em></p>
<p>Once the SDK is installed, run this command to start the process:</p>
<pre class="crayon-plain-tag">gcloud beta auth application-default login</pre>
<p>This will launch a browser to start the authentication process.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Authorization.png" rel="prettyPhoto[gallery-aJAx]"><img class="alignnone size-medium wp-image-6140" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Authorization-265x300.png" alt="Google-Cloud-Platform-Authorization" width="265" height="300" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Authorization-265x300.png 265w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Authorization-768x869.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Authorization.png 824w" sizes="(max-width: 265px) 100vw, 265px" /></a></p>
<p>Log in with the Google credentials associated with your project, and when complete your machine will be setup to access the GCP resources you have enabled for each project. This is done by downloading a file with the associated credentials to your machine (AppData for Windows).</p>
<p>It’s important to understand that this authorizes your entire machine to access your projects via the credentials you authorized. The good news about this is that as new projects are added or updated), your credentials automatically grant access, meaning you don’t have to continuously run the utility to access new project resources from your custom applications.</p>
<p>Now that your machine is authorized, you can call the cloud APIs directly, without any authentication credentials, as they will automatically pull them from your authorized machine. You simply need to specify the project id, and of course, have enabled desired service for the project.</p>
<p>If we run the same project again (after creating a few empty buckets in the storage dashboard), we’ll see our list of buckets as expected, without having to specify any authorization credentials to the code:</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Storage-Buckets.png" rel="prettyPhoto[gallery-aJAx]"><img class="alignnone size-medium wp-image-6141" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Storage-Buckets-300x168.png" alt="Google-Cloud-Platform-Storage-Buckets" width="300" height="168" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Storage-Buckets-300x168.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Storage-Buckets-768x431.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Storage-Buckets-1024x574.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Storage-Buckets.png 1592w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>There are two significant advantages to this setup. First, you don’t have to concern yourself with accidentally checking in important, secret keys to source control, as they are stored in your local machine.</p>
<p>Second, both the Google App Engine and the Google Cloud Engine are already configured to use the same credentials, so if you are deploying your application to either of these services, your app will “just work” without having to manage config files or settings for the different environments.</p>
<p>Of course, this does mean that if you have more than one environment (or additional developers with their own environments) that each needs to remember to perform this step so their projects have access.</p>
<h4>Revoking Default Credentials</h4>
<p>If your work is done or you want to deauthorize a machine, you can do so via the same command-line utility, as described here: https://cloud.google.com/sdk/gcloud/reference/auth/application-default/revoke</p>
<p>Simply run this command and your machine will be deauthorized (the JSON file will be deleted).</p>
<pre class="crayon-plain-tag">gcloud auth application-default revoke</pre>
<h3>Setting Default Credentials Manually (Service Account Key)</h3>
<p>If you do not have the SDK installed or are unable to install it for whatever reason, you can still leverage the Default Credentials by downloading the service key file manually from your account, and setting an environment variable pointing to its location.</p>
<p>To do this, start by going to the API Console Credentials page for your project: <a href="https://console.developers.google.com/project/_/apis/credentials">https://console.developers.google.com/project/_/apis/credentials</a></p>
<p>Create new credentials, selection the option for “Service account key”:</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-Service-Account-Key.png" rel="prettyPhoto[gallery-aJAx]"><img class="alignnone size-medium wp-image-6142" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-Service-Account-Key-300x228.png" alt="Google-Cloud-Platform-Create-Service-Account-Key" width="300" height="228" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-Service-Account-Key-300x228.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-Service-Account-Key.png 766w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>You will be prompted to select or create a service account (more on this later) which will be the account used to access your resources. For now we’ll use the default credential created by Google when we setup the project.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-Service-Account-Key-Credential.png" rel="prettyPhoto[gallery-aJAx]"><img class="alignnone size-medium wp-image-6143" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-Service-Account-Key-Credential-300x189.png" alt="Google-Cloud-Platform-Create-Service-Account-Key-Credential" width="300" height="189" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-Service-Account-Key-Credential-300x189.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-Service-Account-Key-Credential-768x485.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-Service-Account-Key-Credential-1024x647.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-Service-Account-Key-Credential.png 1295w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Select JSON for the key type and create the credential, saving it to a specific location you can find later. In my case I saved it to C:\Google.</p>
<p>Next, create an environment variable, pointing to the file at the location you saved:</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Service-Credential-Environment-Variable.png" rel="prettyPhoto[gallery-aJAx]"><img class="alignnone size-medium wp-image-6144" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Service-Credential-Environment-Variable-300x86.png" alt="Google-Cloud-Platform-Service-Credential-Environment-Variable" width="300" height="86" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Service-Credential-Environment-Variable-300x86.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Service-Credential-Environment-Variable-768x219.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Service-Credential-Environment-Variable-1024x292.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Service-Credential-Environment-Variable.png 1118w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p><em>Note: You may need to reboot before this variable is available.</em></p>
<p>Now you can run the project again and it will successfully authenticate and run.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Storage-Buckets.png" rel="prettyPhoto[gallery-aJAx]"><img class="alignnone size-medium wp-image-6141" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Storage-Buckets-300x168.png" alt="Google-Cloud-Platform-Storage-Buckets" width="300" height="168" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Storage-Buckets-300x168.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Storage-Buckets-768x431.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Storage-Buckets-1024x574.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Storage-Buckets.png 1592w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>However, it’s important to understand the difference between using the Service account key and the Default Credentials. Whereas the Default Credentials will authorize against your entire Google account, the Service account key authorizes against a specific service account defined for a particular project.</p>
<p>If you attempt to change the project id to one to which the service account does not have access, you’ll get an error like this:</p>
<blockquote class="error"><p>The service storage has thrown an exception: Google.GoogleApiException: Google.Apis.Requests.RequestError<br />
Forbidden [403]
Errors [<br />
Message[Forbidden] Location[ &#8211; ] Reason[forbidden] Domain[global]
]</blockquote>
<p>This also means that you can only authorize one service account at a time, so be sure that you are leveraging the appropriate key and location.</p>
<p>Upon deployment to GAE or GCE, your code will again “just work” because as mentioned previously these environments are already configured for access.</p>
<p><em>Note: If you have both Default Credentials setup AND added the environment variable specified here, the environment variable will take precedent and this credential will be used instead of any others.</em></p>
<p>If you’re deploying to a different environment over which you don’t have direct control to set the environment variables, you’ll need another way to authorize your application, and for that we will need a service account.</p>
<h3>Creating a Service Account</h3>
<p>A Service Account is a credential (including a unique email address) you create that will be used to access GCP resources in a specific project. Although the Default Credentials are simple, and recommended you may have need to explicitly authorize your application against a specific credential. One reason in particular is if you need to access resources from more than one account in the same application, or as an account different that the default one associated with the machine.</p>
<p>To create a credential for your own project you need to open the Service Accounts page here: <a href="https://console.developers.google.com/permissions/serviceaccounts">https://console.developers.google.com/permissions/serviceaccounts</a></p>
<p><em>Note: If you are using Google Compute Engine, a default service account will automatically be created for you.</em></p>
<p>You must first select the project, either by clicking the button labeled “Select a project” or selecting one from the “Project” dropdown menu at the top. Creating an account brings up a dialog to define it:</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-Service-Account.png" rel="prettyPhoto[gallery-aJAx]"><img class="alignnone size-medium wp-image-6145" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-Service-Account-300x286.png" alt="Google-Cloud-Platform-Create-Service-Account" width="300" height="286" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-Service-Account-300x286.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-Service-Account-768x733.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Create-Service-Account.png 947w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>You can assign specific roles if necessary, as well as enable G Suite Delegation if you’re using it (more info <a href="https://developers.google.com/identity/protocols/OAuth2ServiceAccount?hl=en_US#delegatingauthority">here</a>), but for now we just want to generate the keys that we’ll need to authenticate the platform.</p>
<p>You can choose between JSON and P12 formats for the private key. However, it appears that for the new .NET libraries, only the JSON option is supported (P12 is for legacy applications not using the new libraries), so we’ll select that option.</p>
<p>Upon creation, the appropriate file will be immediately downloaded to your machine. This is the only time the private key will be generated and available, so keep it safe!</p>
<p>Now that we have a service account created, we can proceed to use the keys to create Google Credentials for accessing GCP services of the project.</p>
<h4>Creating Credentials from JSON Key</h4>
<p>To generate the Google credentials, your C# application needs to be able to access the JSON key file. For our example, I’ve added the key to the project, copying it to the output directory on build.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Service-Account-Key-File.png" rel="prettyPhoto[gallery-aJAx]"><img class="alignnone size-medium wp-image-6146" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Service-Account-Key-File-268x300.png" alt="Google-Cloud-Platform-Service-Account-Key-File" width="268" height="300" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Service-Account-Key-File-268x300.png 268w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Service-Account-Key-File.png 611w" sizes="(max-width: 268px) 100vw, 268px" /></a></p>
<p>Now all I need to do is use this file to generate the appropriate credential and pass it to the service. Here is the modified code, changing just the first two lines inside the try/catch to use our key file instead of the Default credentials:</p>
<pre class="crayon-plain-tag">static void Main(string[] args)
        {

            try
            {
                var credential = GoogleCredential.FromStream(new FileStream("Falafel Test Project-1c0bc1595ad8.p12", FileMode.Open))
                    .CreateScoped(new string[] { StorageService.Scope.DevstorageReadOnly });
                var client = StorageClient.Create();


                var buckets = client.ListBuckets(PROJECT_ID);
                foreach (var bucket in buckets)
                {
                    Console.WriteLine(bucket.Name);
                }
                
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

            Console.ReadLine();
        }</pre>
<p>&nbsp;</p>
<p>Running the project now reveals the same result, assuming of course that we are using the proper key for the account that has access to this project.</p>
<p>You’ll want to be careful when using this option, because obviously you now have your private key exposed inside the project; be sure to exclude this from source control!</p>
<h2>Wrapping Up and Next Steps</h2>
<p>There are several options for authenticating C# applications to access the Google Cloud Platform. While the Google Default Credentials are simple, powerful, and above all recommended, if you need more control over the authentication process, you can authorize your applications against specific service accounts by creating private keys for each application.</p>
<p>In this case we’ve authorized our application to access our own account resources, also known as <a href="https://developers.google.com/identity/protocols/OAuth2ServiceAccount?hl=en_US">two-legged (server to server) authentication</a>. If your application needs to access, process, or edit resources of an end user, we need to first ask for permission. This is called three-legged authentication, and is the subject of our next post.</p>
<p>Until then, as always, I hope this was helpful and thanks for reading!</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/authenticating-your-c-application-for-the-google-cloud-platform-part-1/">Authenticating Your C# Application for the Google Cloud Platform – Part 1</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/authenticating-your-c-application-for-the-google-cloud-platform-part-1/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6138</post-id>	</item>
		<item>
		<title>C# Support for the Google Cloud Platform</title>
		<link>https://blog.falafel.com/c-support-google-cloud-platform/</link>
		<comments>https://blog.falafel.com/c-support-google-cloud-platform/#comments</comments>
		<pubDate>Wed, 18 Jan 2017 17:00:34 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[Cloud Platform]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Google Cloud]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>
		<category><![CDATA[NuGet]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6112</guid>
		<description><![CDATA[<p>This is post 3 of 17 in the series &#8220;Google Cloud for the .NET Developer&#8221; At the end of the day, like most APIs you encounter in the wild, Google services are exposed as standard REST endpoints. If you know how to create, authenticate, and issue an HTTP request, you have everything you need to add Google’s extensive list of services (including the Google Cloud Platform) to your applications. However, most developers prefer to spend their time focused on the implementation of their application, and would rather skip mucking around with boilerplate code to create raw HTTP requests, serialize requests and...</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/c-support-google-cloud-platform/">C# Support for the Google Cloud Platform</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<aside class="wp-post-series-box series-google-cloud-for-the-net-developer">
	<p class="wp-post-series-name">
		This is post 3 of 17 in the series <em>&ldquo;Google Cloud for the .NET Developer&rdquo;</em>	</p>

	
	</aside>
<p>At the end of the day, like most APIs you encounter in the wild, Google services are exposed as standard REST endpoints. If you know how to create, authenticate, and issue an HTTP request, you have everything you need to add Google’s <a href="https://developers.google.com/products/">extensive list of services</a> (including the Google Cloud Platform) to your applications.</p>
<p>However, most developers prefer to spend their time focused on the implementation of their application, and would rather skip mucking around with boilerplate code to create raw HTTP requests, serialize requests and responses, and handle errors. Depending on how many services an application consumes, such operations can represent a significant amount of development time.</p>
<p>Fortunately, like most popular public APIs, Google offers a Software Development Kit (SDK) for a majority of their services, for many different languages and platforms, including .NET via C#. In fact, the <a href="https://developers.google.com/api-client-library/dotnet/">Google APIs Client Library for .NET</a> has been around for a while, offering <a href="https://developers.google.com/api-client-library/dotnet/apis/">C# libraries for Google Services</a> including the Google Cloud Platform.</p>
<h2>Brand New Libraries for Google Cloud Platform</h2>
<p>The Client Library for .NET offers a collection of libraries for accessing established services like <a href="https://developers.google.com/api-client-library/dotnet/apis/youtube/v3">YouTube</a>, <a href="https://developers.google.com/api-client-library/dotnet/apis/calendar/v3">Calendar</a>, etc. However, although this library collection does include support for various Google Cloud services, there is now a new set of .NET libraries for the Google Cloud Platform available here: <a href="https://cloud.google.com/dotnet">https://cloud.google.com/dotnet</a></p>
<p><a href="https://googlecloudplatform.github.io/google-cloud-dotnet/">The new C# libraries</a>, led by noted C# expert and Microsoft MVP Jon Skeet, offer a full-featured C# experience for developers looking to leverage GCP in their applications. These libraries are also open source, and <a href="https://github.com/GoogleCloudPlatform/google-cloud-dotnet">available on GitHub</a> for developers to clone as well and contribute to the project. There is also <a href="https://googlecloudplatform.github.io/google-cloud-dotnet/docs/index.html">API documentation</a> available including the list of supported products and their release status (beta, alpha, etc.).</p>
<p>As of the writing of this post, the original .NET Client Library is still supported for GCP, and many of the new libraries are in beta or alpha stages. However, it is still recommended that you leverage the new libraries, especially for new projects, as these are the libraries that will be updated and supported in the future.</p>
<h2>Getting Started Guides</h2>
<p>Each supported product has a page to get you started, documenting installation, authentication, and even sample code demonstrating usage of the library. These are linked from both the <a href="https://github.com/GoogleCloudPlatform/google-cloud-dotnet">project Github homepage</a> and the <a href="http://googlecloudplatform.github.io/google-cloud-dotnet/docs/index.html">API Documentation</a> page.</p>
<p>As of the writing of this post, the following libraries are available, separated by release status:</p>
<p><strong>Late Beta</strong></p>
<ul>
<li><strong><a href="http://googlecloudplatform.github.io/google-cloud-dotnet/docs/Google.Cloud.Storage.V1/">Google Cloud Storage</a></strong></li>
<li><strong><a href="http://googlecloudplatform.github.io/google-cloud-dotnet/docs/Google.Cloud.BigQuery.V2/">Google BigQuery</a></strong></li>
<li><strong><a href="http://googlecloudplatform.github.io/google-cloud-dotnet/docs/Google.Cloud.Datastore.V1/">Google Cloud Datastore</a></strong></li>
<li><strong><a href="http://googlecloudplatform.github.io/google-cloud-dotnet/docs/Google.Cloud.Logging.V2/">Google Stackdriver Logging</a></strong></li>
</ul>
<p><strong>Beta</strong></p>
<ul>
<li><strong><a href="http://googlecloudplatform.github.io/google-cloud-dotnet/docs/Google.Cloud.PubSub.V1/">Google Cloud PubSub</a></strong></li>
<li><strong><a href="http://googlecloudplatform.github.io/google-cloud-dotnet/docs/Google.Cloud.Language.V1/">Google Cloud Natural Language</a></strong></li>
<li><strong><a href="http://googlecloudplatform.github.io/google-cloud-dotnet/docs/Google.Cloud.Monitoring.V3/">Stackdriver Monitoring</a></strong></li>
<li><strong><a href="http://googlecloudplatform.github.io/google-cloud-dotnet/docs/Google.Cloud.ErrorReporting.V1Beta1/">Stackdriver Error Reporting</a></strong></li>
<li><strong><a href="http://googlecloudplatform.github.io/google-cloud-dotnet/docs/Google.Cloud.Trace.V1/">Stackdriver Trace</a></strong></li>
<li><strong><a href="http://googlecloudplatform.github.io/google-cloud-dotnet/docs/Google.Cloud.Diagnostics.AspNet/">Google Cloud Diagnostics for ASP.NET</a></strong></li>
</ul>
<p><strong>Alpha</strong></p>
<ul>
<li><strong><a href="http://googlecloudplatform.github.io/google-cloud-dotnet/docs/Google.Cloud.Metadata.V1">Google Cloud Metadata</a></strong></li>
<li><strong><a href="http://googlecloudplatform.github.io/google-cloud-dotnet/docs/Google.Cloud.Vision.V1/">Google Cloud Vision</a></strong></li>
<li><strong><a href="http://googlecloudplatform.github.io/google-cloud-dotnet/docs/Google.Cloud.Speech.V1Beta1/">Google Cloud Speech</a></strong></li>
</ul>
<h3>Nuget</h3>
<p>Each of the Google Cloud libraries is available via <a href="https://www.nuget.org/profiles/google-cloud">Nuget</a>, so adding them to your project is as simple as right-clicking your project, selecting Manage Nuget Packages, and searching for the desired library.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Nuget-Pacakges.png" rel="prettyPhoto[gallery-O4kk]"><img class="alignnone wp-image-6113 size-medium" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Nuget-Pacakges-267x300.png" alt="Google Cloud Platform Nuget Pacakges" width="267" height="300" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Nuget-Pacakges-267x300.png 267w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Nuget-Pacakges-768x864.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Nuget-Pacakges-910x1024.png 910w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Nuget-Pacakges.png 1068w" sizes="(max-width: 267px) 100vw, 267px" /></a></p>
<p><em>Note: Be sure to select the option to “Include prerelease” since many of these libraries are still in beta/alpha stages.</em></p>
<p>It’s also important to note that your search may reveal the original libraries for .NET, so be sure you’re selecting the correct library (many of the new packages serve as wrappers to the older libraries, so they may also be included as dependencies). The newer libraries have an updated logo and namespace, so be sure to look carefully at the naming to ensure you’ve selected the correct one.</p>
<p><a href="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Nuget-Pacakges-Prerelease.png" rel="prettyPhoto[gallery-O4kk]"><img class="alignnone size-medium wp-image-6114" src="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Nuget-Pacakges-Prerelease-300x148.png" alt="Google Cloud Platform Nuget Pacakges Prerelease" width="300" height="148" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Nuget-Pacakges-Prerelease-300x148.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Nuget-Pacakges-Prerelease-768x380.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/Google-Cloud-Platform-Nuget-Pacakges-Prerelease.png 926w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<h2>Tutorial Project</h2>
<p>As a helpful resource to get you started, Google has created a <a href="https://github.com/GoogleCloudPlatform/getting-started-dotnet/">complete C# sample</a> that leverages several cloud services together in one project for you to test, run and deploy to GCP. There is also an associated, thoroughly detailed, <a href="https://cloud.google.com/dotnet/docs/getting-started/tutorial-app">step-by-step tutorial</a> available that guides you through each facet of the project as well as the Google services they leverage. You get a full tour of several services including live deployment and even resource scaling.</p>
<p>If you’re new to GCP, this is a fantastic place to start, so I encourage you to read through the entire interactive tutorial to quickly get familiar with the Google Cloud Platform.</p>
<p><a href="https://cloud.google.com/dotnet/docs/getting-started/tutorial-app">Bookshelf App Tutorial</a></p>
<p>In addition, there is a collection of C# samples available on Github here: https://github.com/GoogleCloudPlatform/dotnet-docs-samples</p>
<h2>Wrapping up and Next Steps</h2>
<p>The Google Cloud Platform has a lot to offer C# developers, and the library refresh makes it easier than ever to integrate these services into your applications. Although still in early form, these libraries are growing quickly, both in terms of availability and quality, and easily installable via Nuget so you can start using these today!</p>
<p>However, although installation of the supported libraries into your own projects is easy enough, there’s an important step we have to complete before they can actually be used: Authentication. That will be the subject of a future post so stay tuned!</p>
<p>Until then, as always, I hope this was helpful, and thanks for reading!</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/c-support-google-cloud-platform/">C# Support for the Google Cloud Platform</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/c-support-google-cloud-platform/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6112</post-id>	</item>
		<item>
		<title>Read/Write data from/to USB thumb drive on a Windows IoT Core device</title>
		<link>https://blog.falafel.com/readwrite-data-fromto-usb-thumb-drive-windows-iot-core-device/</link>
		<comments>https://blog.falafel.com/readwrite-data-fromto-usb-thumb-drive-windows-iot-core-device/#comments</comments>
		<pubDate>Tue, 17 Jan 2017 19:37:10 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Blogs]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Fun]]></category>
		<category><![CDATA[IoT]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Multi-Device]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[Windows Universal Apps]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[Windows IoT Core]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6148</guid>
		<description><![CDATA[<p>Currently, universal apps are sandboxed to the point of blocking you from reading/writing data files to a removable USB drive on Windows IoT Core devices. This post will show you a work around if you really need to do this. Now, understand that this is not for store apps. If you submit an app using this work around, it will likely get rejected. However, for internal projects, it will definitely work, and work well. This is a great way of reading application initialization data and writing log data in a test apparatus and laboratory setting. Particularly when a network or...</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/readwrite-data-fromto-usb-thumb-drive-windows-iot-core-device/">Read/Write data from/to USB thumb drive on a Windows IoT Core device</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Currently, universal apps are sandboxed to the point of blocking you from reading/writing data files to a removable USB drive on <a href="https://developer.microsoft.com/en-us/windows/iot" target="_blank">Windows IoT Core</a> devices. This post will show you a work around if you really need to do this. Now, understand that this is not for store apps. If you submit an app using this work around, it will likely get rejected. However, for internal projects, it will definitely work, and work well.</p>
<p>This is a great way of reading application initialization data and writing log data in a test apparatus and laboratory setting. Particularly when a network or internet connection is not reliable or available in your test apparatus/laboratory setting. You can manage application settings by editing a simple <a href="https://en.wikipedia.org/wiki/JSON" target="_blank">JSON </a>file at your convenience and copying it onto a thumb drive. Then just plug it into an IoT device-based system. Data gets read and written to the thumb drive and is easily accessible by just removing the thumb drive.</p>
<p>The first thing you need to do to your <a href="https://msdn.microsoft.com/en-us/windows/uwp/get-started/whats-a-uwp" target="_blank">Windows Universal</a> application is enable a couple of capabilities.</p>
<div id="attachment_6149" style="width: 1034px" class="wp-caption alignnone"><a href="https://blog.falafel.com/wp-content/uploads/2017/01/iot1.png" rel="prettyPhoto[gallery-O4U8]"><img class="wp-image-6149 size-large" src="https://blog.falafel.com/wp-content/uploads/2017/01/iot1-1024x1004.png" alt="Fig 1" width="1024" height="1004" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/iot1-1024x1004.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/iot1-300x294.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/iot1-768x753.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/iot1-50x50.png 50w, https://blog.falafel.com/wp-content/uploads/2017/01/iot1.png 1505w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><p class="wp-caption-text">Fig 1</p></div>
<p>The &#8220;Pictures Library&#8221; and the &#8220;Removable Storage&#8221; capabilities need to be enabled. Why the &#8220;Pictures Library&#8221;? Because, as of build 14393, you can&#8217;t read or write files other than what are recognized as those that belong in the &#8220;Pictures Library&#8221; when you have that capability enabled. If you enabled the video or music capabilities, you could write those kind of files as well. There is no option for text, doc, or any other files. In this example, we&#8217;re going to stick with picture files.</p>
<p>Now you need an initialization file to put onto your thumb drive. We&#8217;re going to set key/value pairs in a JSON format. In this example, we&#8217;ll have a value that updates our page title, an integer value, and the log filename.</p>
<p>{<br />
&#8220;MAINPAGETITLE&#8221;:&#8221;My Removable Title&#8221;,<br />
&#8220;MAININT&#8221;:3,<br />
&#8220;LOGFILENAME&#8221;:&#8221;MyLogFile&#8221;,<br />
}</p>
<p>Create a new text file in your favorite editor, but when you save it to the root of your thumb drive make sure you save it with a .jpg extension. This is what it should look like.</p>
<div id="attachment_6151" style="width: 1034px" class="wp-caption alignnone"><a href="https://blog.falafel.com/wp-content/uploads/2017/01/iot2.png" rel="prettyPhoto[gallery-O4U8]"><img class="wp-image-6151 size-large" src="https://blog.falafel.com/wp-content/uploads/2017/01/iot2-1024x588.png" alt="Fig 2" width="1024" height="588" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/iot2-1024x588.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/iot2-300x172.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/iot2-768x441.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/iot2.png 1544w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><p class="wp-caption-text">Fig 2</p></div>
<p>Your system will recognize it as a .jpg, which is OK because we know it&#8217;s just JSON data hiding.</p>
<p>In your application you need to create a class to handle the JSON data in your file.</p>
<div id="attachment_6152" style="width: 622px" class="wp-caption alignnone"><a href="https://blog.falafel.com/wp-content/uploads/2017/01/iot3.png" rel="prettyPhoto[gallery-O4U8]"><img class="wp-image-6152" src="https://blog.falafel.com/wp-content/uploads/2017/01/iot3-1024x465.png" alt="Fig 3" width="612" height="278" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/iot3-1024x465.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/iot3-300x136.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/iot3-768x349.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/iot3.png 1028w" sizes="(max-width: 612px) 100vw, 612px" /></a><p class="wp-caption-text">Fig 3</p></div>
<p>To read the JSON file from the thumb drive, we need to add the following method with the name of our file as a parameter.</p>
<div id="attachment_6153" style="width: 1034px" class="wp-caption alignnone"><a href="https://blog.falafel.com/wp-content/uploads/2017/01/iot4.png" rel="prettyPhoto[gallery-O4U8]"><img class="size-large wp-image-6153" src="https://blog.falafel.com/wp-content/uploads/2017/01/iot4-1024x366.png" alt="Fig 4" width="1024" height="366" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/iot4-1024x366.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/iot4-300x107.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/iot4-768x275.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><p class="wp-caption-text">Fig 4</p></div>
<p>Fig 4-1: Call <a href="https://msdn.microsoft.com/en-us/library/windows/apps/br227280.aspx" target="_blank">GetFoldersAsync</a> from the <a href="https://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.knownfolders.removabledevices.aspx" target="_blank">KnownFolders.RemovableDevices</a> object to get a reference to all of the removable drives.<br />
Fig 4-2: Get a reference to the thumb drive by looking for a drive whose name contains &#8220;USB DISK&#8221;.<br />
Fig 4-3: To open the file, we call the <a href="https://msdn.microsoft.com/en-us/library/windows/apps/br227250.aspx" target="_blank">CreateFileAsync</a> method.<br />
Fig 4-4: Now we open a stream reader from our opened file with a call to <a href="https://msdn.microsoft.com/en-us/library/hh582102(v=vs.110).aspx" target="_blank">OpenStreamForReadAsync</a>.<br />
Fig 4-5: Read stream content with a call to <a href="https://msdn.microsoft.com/en-us/library/system.io.streamreader.readtoendasync(v=vs.110).aspx" target="_blank">ReadToEndAsync</a>.<br />
Fig 4-6: Finally, we populate the data from our file into a reference of our MyAppData class with a call to <a href="http://www.newtonsoft.com/json/help/html/Overload_Newtonsoft_Json_JsonConvert_DeserializeObject.htm" target="_blank">DeserializeObject</a>.</p>
<p>With this call in place you can update the app data class and the JSON file with anything you need to initialize your application in most anyway you want.</p>
<p>In this example, we write our data file into a new folder for each day. In order to write data to the thumb drive we need to add the following method.</p>
<div id="attachment_6154" style="width: 1034px" class="wp-caption alignnone"><a href="https://blog.falafel.com/wp-content/uploads/2017/01/iot5.png" rel="prettyPhoto[gallery-O4U8]"><img class="size-large wp-image-6154" src="https://blog.falafel.com/wp-content/uploads/2017/01/iot5-1024x402.png" alt="Fig 5" width="1024" height="402" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/iot5-1024x402.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/iot5-300x118.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/iot5-768x301.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><p class="wp-caption-text">Fig 5</p></div>
<p>Fig 5-1: In this example, I create a new folder for each day. This line builds a folder name using the filename as a prefix followed by the month, day, and year.<br />
Fig 5-2: Just like reading the JSON file in Fig 4, we need to get a reference to all the removable drives and find the USB thumb drive.<br />
Fig 5-3: We create the daily folder with a call to <a href="https://msdn.microsoft.com/en-us/library/windows/apps/br227257.aspx" target="_blank">CreateFolderAsync</a> and get a reference to it.<br />
Fig 5-4: Now we create the data file in the new daily folder with a call to <a href="https://msdn.microsoft.com/en-us/library/windows/apps/br227250.aspx" target="_blank">CreateFileAsync</a>.</p>
<p>The following method shows how easy it is to writing data to our file.</p>
<div id="attachment_6155" style="width: 1034px" class="wp-caption alignnone"><a href="https://blog.falafel.com/wp-content/uploads/2017/01/iot6.png" rel="prettyPhoto[gallery-O4U8]"><img class="size-large wp-image-6155" src="https://blog.falafel.com/wp-content/uploads/2017/01/iot6-1024x338.png" alt="Fig 6" width="1024" height="338" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/iot6-1024x338.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/iot6-300x99.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/iot6-768x254.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><p class="wp-caption-text">Fig 6</p></div>
<p>Fig 6-1: Open a stream to our data file with a call to <a href="https://msdn.microsoft.com/en-us/library/hh582148(v=vs.110).aspx" target="_blank">OpenStreamForWriteAsync</a>.<br />
Fig 6-2: Now that we have a stream opened to our file, writing to the file follows a standard procedure of writing to a DataWriter and flushing the stream.</p>
<p>To demonstrate how to use these functions we have a simple Universal Windows App example that we&#8217;ll run on a <a href="https://www.raspberrypi.org/products/raspberry-pi-2-model-b/" target="_blank">Raspberry Pi2</a>, or other suitable Windows IoT Core device. The XAML for our app has just three elements. We have a TextBlock to display our title, a Button that executes our write procedure, and a TextBox to store the data that we&#8217;ll write to our data file. Note that we&#8217;re defaulting the IsEnabled property of the button to False.</p>
<div id="attachment_6156" style="width: 1034px" class="wp-caption alignnone"><a href="https://blog.falafel.com/wp-content/uploads/2017/01/iot8.png" rel="prettyPhoto[gallery-O4U8]"><img class="size-large wp-image-6156" src="https://blog.falafel.com/wp-content/uploads/2017/01/iot8-1024x187.png" alt="Fig 7" width="1024" height="187" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/iot8-1024x187.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/iot8-300x55.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/iot8-768x140.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><p class="wp-caption-text">Fig 7</p></div>
<p>In the Loaded event handler, we open and read our app file and initialize our data file.</p>
<div id="attachment_6157" style="width: 1034px" class="wp-caption alignnone"><a href="https://blog.falafel.com/wp-content/uploads/2017/01/iot9.png" rel="prettyPhoto[gallery-O4U8]"><img class="size-large wp-image-6157" src="https://blog.falafel.com/wp-content/uploads/2017/01/iot9-1024x360.png" alt="Fig 8" width="1024" height="360" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/iot9-1024x360.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/iot9-300x105.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/iot9-768x270.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><p class="wp-caption-text">Fig 8</p></div>
<p>Fig 8-1: We call our OpenAppFile method with the name of our app file.<br />
Fig 8-2: Now that our AppData reference is loaded with the data from our file, we set our title TextBlock and set our integer value to our TextBox. No binding for this example; we&#8217;re keeping it simple.<br />
Fig 8-3: We call our InitLog method to initialize and create the data file for writing.<br />
Fig 8-4: We use the <a href="https://msdn.microsoft.com/en-us/library/dd270696(v=vs.110).aspx" target="_blank">ContinueWith</a> task method to set the IsEnabled property to True after the InitLog method is completed.</p>
<p>In the button click event handler we write to our data file</p>
<div id="attachment_6158" style="width: 1034px" class="wp-caption alignnone"><a href="https://blog.falafel.com/wp-content/uploads/2017/01/iot10.png" rel="prettyPhoto[gallery-O4U8]"><img class="size-large wp-image-6158" src="https://blog.falafel.com/wp-content/uploads/2017/01/iot10-1024x330.png" alt="Fig 9" width="1024" height="330" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/iot10-1024x330.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/iot10-300x97.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/iot10-768x247.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><p class="wp-caption-text">Fig 9</p></div>
<p>Fig 9-1: First we set our button IsEnabled property to False to prevent double clicking.<br />
Fig 9-2: Now we call our WriteLogAsync method to write our data to our data file.<br />
Fig 9-3: We use the <a href="https://msdn.microsoft.com/en-us/library/dd270696(v=vs.110).aspx" target="_blank">ContinueWith</a> task method to set the IsEnabled property of the button to True after the WriteLogAsync method is completed.</p>
<p>With the software in place and our JSON file saved to our thumb drive, it&#8217;s time to plug it into our Pi2 and run our application.</p>
<div id="attachment_6150" style="width: 1034px" class="wp-caption alignnone"><a href="https://blog.falafel.com/wp-content/uploads/2017/01/P1130472.jpg" rel="prettyPhoto[gallery-O4U8]"><img class="wp-image-6150 size-large" src="https://blog.falafel.com/wp-content/uploads/2017/01/P1130472-1024x451.jpg" alt="Fig 10" width="1024" height="451" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/P1130472-1024x451.jpg 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/P1130472-300x132.jpg 300w, https://blog.falafel.com/wp-content/uploads/2017/01/P1130472-768x338.jpg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><p class="wp-caption-text">Fig 10</p></div>
<p>When the app first comes up, you should see this something like this.</p>
<div id="attachment_6159" style="width: 1034px" class="wp-caption alignnone"><a href="https://blog.falafel.com/wp-content/uploads/2017/01/iot112.png" rel="prettyPhoto[gallery-O4U8]"><img class="wp-image-6159 size-large" src="https://blog.falafel.com/wp-content/uploads/2017/01/iot112-1024x251.png" alt="Fig 11" width="1024" height="251" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/iot112-1024x251.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/iot112-300x74.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/iot112-768x188.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><p class="wp-caption-text">Fig 11</p></div>
<p>Now you can write something to the data file by filling in the TextBox and pressing the Write Log button.</p>
<div id="attachment_6160" style="width: 1034px" class="wp-caption alignnone"><a href="https://blog.falafel.com/wp-content/uploads/2017/01/iot113.png" rel="prettyPhoto[gallery-O4U8]"><img class="wp-image-6160 size-large" src="https://blog.falafel.com/wp-content/uploads/2017/01/iot113-1024x327.png" alt="Fig 12" width="1024" height="327" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/iot113-1024x327.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/iot113-300x96.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/iot113-768x245.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/iot113.png 1575w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><p class="wp-caption-text">Fig 12</p></div>
<p>Remove the thumb drive, plug it into your computer, and browse to your thumb drive. The computer will think your data file is a .jpg. However, we know that it&#8217;s not. Right click on the data file and open with the text editor of your choice.</p>
<div id="attachment_6161" style="width: 1034px" class="wp-caption alignnone"><a href="https://blog.falafel.com/wp-content/uploads/2017/01/iot7.png" rel="prettyPhoto[gallery-O4U8]"><img class="wp-image-6161 size-large" src="https://blog.falafel.com/wp-content/uploads/2017/01/iot7-1024x885.png" alt="Fig 13" width="1024" height="885" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/iot7-1024x885.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/iot7-300x259.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/iot7-768x664.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><p class="wp-caption-text">Fig 13</p></div>
<p>Now you can view your data.</p>
<div id="attachment_6162" style="width: 1034px" class="wp-caption alignnone"><a href="https://blog.falafel.com/wp-content/uploads/2017/01/iot111.png" rel="prettyPhoto[gallery-O4U8]"><img class="wp-image-6162 size-large" src="https://blog.falafel.com/wp-content/uploads/2017/01/iot111-1024x760.png" alt="Fig 14" width="1024" height="760" srcset="https://blog.falafel.com/wp-content/uploads/2017/01/iot111-1024x760.png 1024w, https://blog.falafel.com/wp-content/uploads/2017/01/iot111-300x223.png 300w, https://blog.falafel.com/wp-content/uploads/2017/01/iot111-768x570.png 768w, https://blog.falafel.com/wp-content/uploads/2017/01/iot111.png 1334w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><p class="wp-caption-text">Fig 14</p></div>
<p>I found this very useful for an automated electronic tester we were building. This tester was going to be in a factory setting where a reliable internet connection was not an option. We needed to be able to collect the data and have a way to store it on removable media that could be uploaded to headquarters at a convenient time. We also needed a way to be able to update the app settings day by day. In any case, this work around proved very useful for our situation. Maybe it will be useful for one of your needs someday. You can download the sample app <a href="https://github.com/physicspackage/IoTRemovableFile" target="_blank">here</a>.</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/readwrite-data-fromto-usb-thumb-drive-windows-iot-core-device/">Read/Write data from/to USB thumb drive on a Windows IoT Core device</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/readwrite-data-fromto-usb-thumb-drive-windows-iot-core-device/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6148</post-id>	</item>
		<item>
		<title>Google Cloud Platform (GCP) Overview</title>
		<link>https://blog.falafel.com/google-cloud-platform-overview/</link>
		<comments>https://blog.falafel.com/google-cloud-platform-overview/#respond</comments>
		<pubDate>Tue, 17 Jan 2017 17:00:49 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[Cloud Platform]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6110</guid>
		<description><![CDATA[<p>This is post 2 of 17 in the series &#8220;Google Cloud for the .NET Developer&#8221; The list of products available in Google Cloud Platform, while shorter than the lists from Azure or AWS, can still seem quite daunting. Here&#8217;s a quick overview of what&#8217;s available in the Google Cloud Platform (GCP) specifically for .NET applications. Compute GCP offers many products under the Compute umbrella, but most are not easily accessible to the Windows Server + IIS + .NET developer. The two main offerings of interest are Compute Engine and App Engine. Compute Engine Compute Engine is the family of services focused...</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/google-cloud-platform-overview/">Google Cloud Platform (GCP) Overview</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<aside class="wp-post-series-box series-google-cloud-for-the-net-developer">
	<p class="wp-post-series-name">
		This is post 2 of 17 in the series <em>&ldquo;Google Cloud for the .NET Developer&rdquo;</em>	</p>

	
	</aside>
<p>The list of products available in Google Cloud Platform, while shorter than the lists from Azure or AWS, can still seem quite daunting. Here&#8217;s a quick overview of what&#8217;s available in the Google Cloud Platform (GCP) specifically for .NET applications.</p>
<h1>Compute</h1>
<p>GCP offers many products under the Compute umbrella, but most are not easily accessible to the Windows Server + IIS + .NET developer. The two main offerings of interest are Compute Engine and App Engine.</p>
<h2>Compute Engine</h2>
<p>Compute Engine is the family of services focused on the management of VMs in the Google Cloud. This is truly Infrastructure as a Service (IaaS). This includes single instances, instance images, snapshots, disks, instance templates, and auto-scaling instance groups. In GCP, you can create Windows Server VMs, and the licensing and activation are handled entirely by GCP and simply rolled into the cost of the VM. This is the only way to run .NET 4.x in GCP.</p>
<h2>App Engine</h2>
<p>If Compute Engine is Infrastructure as a Service, App Engine is Platform as a Service (PaaS). With App Engine, the focus is more on running your code in managed environments and less about the management of the metal itself. In addition to that, App Engine adds automatic health checks, scaling, traffic splitting, memcache, logs, task queues, and more. You can write new ASP.NET Core applications that can be hosted in App Engine&#8217;s flexible environment with what they call a custom runtime&#8211;in this case, requesting the official Microsoft .NET Core Images from the repository.</p>
<h1>Storage</h1>
<p>Once you get past the limited support for Windows and .NET in GCP, everything else really starts to open up. There&#8217;s a NuGet package for every GCP service, making it easy to consume them from any .NET project. Here are some of the available storage options:</p>
<table>
<thead>
<tr>
<td><strong>Name</strong></td>
<td><strong>Description</strong></td>
</tr>
</thead>
<tbody>
<tr>
<td>Cloud Storage</td>
<td>File-oriented storage with geo-redundancy, edge-caching, support for video streaming, lifecycle management, access control, and more.</td>
</tr>
<tr>
<td>Cloud SQL</td>
<td>Managed MySQL in the cloud. It may not be SQL Server, but it is supported by Entity Framework, so if you primarily interface with a relational database through an ORM, you might not even notice a difference.</td>
</tr>
<tr>
<td>Cloud Bigtable</td>
<td>A unique offering not available in any other cloud! Managed Bigtable, which is a NOSQL database of the &#8220;column family&#8221; variety, well-suited to handling truly huge amounts of data.</td>
</tr>
<tr>
<td>Cloud Datastore</td>
<td>Another managed NOSQL database, this one of the &#8220;document&#8221; variety. Document databases are some of the most popular and well-known NOSQL databases, best suited for storing denormalized, heterogeneous and/or hierarchical data.</td>
</tr>
</tbody>
</table>
<h1>Networking</h1>
<p>GCP offers a variety of networking services, including virtual private networks, load balancing, Content Delivery Networks (CDNs), the ability to create a network that enables interconnectivity between GCP and external infrastructure, and even the ability to manage Domain Names.</p>
<h1>Big Data</h1>
<p>In addition to Cloud Bigtable, GCP offers several other services that support the unique needs of big data.</p>
<table>
<thead></thead>
<tbody>
<tr>
<td>Name</td>
<td>Description</td>
</tr>
</tbody>
<tbody>
<tr>
<td>BigQuery</td>
<td>Built on Bigtable, the key differences are that BigQuery offers full ANSI SQL support, and the billing works differently. When at rest, data in BigQuery costs much less to store than Bigtable. Billing occurs when the data is actually queried, and is per TB of data actually read by the query.</td>
</tr>
<tr>
<td>Cloud Dataflow</td>
<td>Stream data processing with automatic scaling, partitioning, and windowing</td>
</tr>
<tr>
<td>Cloud Pub/Sub</td>
<td>A managed publish/subscribe service with a flexible variety of delivery options, including push/pull and fan-in/fan-out. With this service, you can implement a variety of communication patterns, including task queues, async workflows, event notifications, and more.</td>
</tr>
</tbody>
</table>
<h1>Machine Learning</h1>
<p>The GCP Machine Learning family of services includes a multitude of APIs that encapsulate models already trained to perform tasks such as analyze natural language, convert speech to text, translate languages, recognize things in images, and more. Then there is the Machine Learning Service, currently in beta, which allows you to train your own model using the TensorFlow framework.</p>
<h1>Management</h1>
<p>GCP offers a unified management service called Stackdriver, which enables monitoring, logging, error reporting, tracing, and even in-production debugging (debugging not available for any .NET languages, sadly). It also offers Cloud Endpoints, a service that lets you define a RESTful API and then surrounds that with authentication, logging, and monitoring. The implementation of the API can be hosted on App Engine Flexible, which in turn can contain ASP.NET Core applications.</p>
<h1>Developer Tools</h1>
<p>For the ASP.NET developer, GCP offers a cross-platform CLI, a Visual Studio extension, and tools for PowerShell.</p>
<h1>Identity &amp; Security</h1>
<p>GCP has its own implementation of Identity and Access Management (IAM) called Cloud IAM. Out of the box, it offers not only standard roles for users, but also specialized roles and fine-grained control relative to specific GCP resources. For example, you can create an IAM access control policy that grants the Subscriber role for a specific Cloud Pub/Sub topic. Cloud IAM automatically creates a full audit trail of permissions as well.</p>
<p>That covers the highlights of what&#8217;s available on GCP, especially the products of interest for .NET developers. There are even more that I glossed over or are bundled with other products as well. Check out the full list at <a href="http://cloud.google.com/products" target="_blank">http://cloud.google.com/products</a>.</p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/google-cloud-platform-overview/">Google Cloud Platform (GCP) Overview</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/google-cloud-platform-overview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6110</post-id>	</item>
		<item>
		<title>Why Organizations should choose GCP &#8211; A Business Perspective</title>
		<link>https://blog.falafel.com/organizations-choose-gcp-business-perspective/</link>
		<comments>https://blog.falafel.com/organizations-choose-gcp-business-perspective/#respond</comments>
		<pubDate>Tue, 17 Jan 2017 00:08:50 +0000</pubDate>
		<dc:creator><![CDATA[Falafel Posts]]></dc:creator>
				<category><![CDATA[Cloud Platform]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Cloud Implementation]]></category>
		<category><![CDATA[Cloud Storage]]></category>
		<category><![CDATA[GCP]]></category>
		<category><![CDATA[Google Cloud]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>
		<category><![CDATA[Hybrid Cloud]]></category>

		<guid isPermaLink="false">https://blog.falafel.com/?p=6136</guid>
		<description><![CDATA[<p>Cloud services reduce the effort needed to manage infrastructure, provision servers and configure networks. Today the cloud market is primarily dominated by Amazon Web Services, followed by Microsoft Azure. As the new kid on the block, GCP is the newest entrant to a highly profitable and competitive landscape. In this blog series, the team will discuss GCP services and implementation differences between GCP, AWS, and Azure. This post explores GCP from a business point of view — what to consider when making an informed decision for your organization. </p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/organizations-choose-gcp-business-perspective/">Why Organizations should choose GCP &#8211; A Business Perspective</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<aside class="wp-post-series-box series-google-cloud-for-the-net-developer">
	<p class="wp-post-series-name">
		This is post 1 of 17 in the series <em>&ldquo;Google Cloud for the .NET Developer&rdquo;</em>	</p>

	
	</aside>
<p><span style="font-weight: 400;">Cloud services reduce the effort needed to manage infrastructure, provision servers and configure networks. Today the cloud market is primarily dominated by Amazon Web Services, followed by Microsoft Azure. As the new kid on the block, GCP is the newest entrant to a highly profitable and competitive landscape.</span></p>
<p style="padding-left: 30px;"><i><span style="font-weight: 400;">Our team at Falafel Software have built applications for our clients on both Amazon Web Services (AWS) and Microsoft Azure for some time. Because of Falafel’s stellar reputation, we have been selected as the first West Coast partner for Google Cloud Platform (GCP) .NET solutions. As part of our partnership with Google, we will offer training, mentoring and consulting for the Google Cloud. </span></i></p>
<p><span style="font-weight: 400;">In this blog series, the team will discuss GCP services and implementation differences between GCP, AWS, and Azure. This post explores GCP from a </span><i><span style="font-weight: 400;">business</span></i><span style="font-weight: 400;"> point of view &#8212; what to consider when making an informed decision for your organization. </span></p>
<h2><span style="font-weight: 400;">Why go with Cloud computing?</span></h2>
<p><span style="font-weight: 400;">For a company to remain competitive, it needs to reduce costs, increase business agility and remain flexible to handle growing needs. Infrastructure-as-a-service (IaaS) or public cloud services, are an indispensable part of your IT arsenal that allow you to focus on your core business. Here are 5 reasons to move to the cloud:</span></p>
<ul>
<li><i><span style="font-weight: 400;">Business Efficiency</span></i><span style="font-weight: 400;"> &#8211; Freeing your organization from managing a large IT department allows you to efficiently run business operations and focus on decision making that affects the future of your company. You free yourself, and your team, from worrying about how business activity impacts IT. </span></li>
<li><i><span style="font-weight: 400;">Reduce Staffing</span></i><span style="font-weight: 400;"> &#8211; Keep only the key technical specialization and engineering staff that your business requires, without adding operational personnel. </span></li>
<li><i><span style="font-weight: 400;">Scaling</span></i><span style="font-weight: 400;"> &#8211; To handle seasonal spikes, unexpected growth, or other changes in traffic, use cloud services to ramp up resources without purchasing hardware and software that goes unused during the rest of the year.</span></li>
<li><i><span style="font-weight: 400;">Reduce Capital Spending</span></i> <span style="font-weight: 400;">&#8211; Why make large capital investments for hardware, data centers, and staff when you can use the savings for business investment? Instead of risky large outlays, your cost is reduced to monthly billing. </span></li>
<li><i><span style="font-weight: 400;">Instant Anywhere Access</span></i><span style="font-weight: 400;"> &#8211; Cloud services allow your team to work anywhere with instant access. Team members only need internet connections and authorized access. This means better work conditions, a larger pool of talent (they can work remotely from anywhere) and more efficiency at getting things done. </span></li>
</ul>
<h2><span style="font-weight: 400;">Why GCP?</span></h2>
<p><span style="font-weight: 400;">We were invited to meet with Google at both their Chicago and Mountain View headquarters to discuss GCP from a .NET perspective. Since then, we have decided to move one of our applications from Azure to GCP, in part to see how easy it would be to migrate from one solution provider to another, and to compare performance between the two. </span></p>
<p><span style="font-weight: 400;">Although GCP is relatively new compared to AWS and Azure, Google has been beefing up their cloud offering. Not only has Google added </span><a href="https://cloud.google.com/about/locations/"><span style="font-weight: 400;">new data centers</span></a><span style="font-weight: 400;"> worldwide since last year, they also </span><a href="https://cloud.google.com/pricing/"><span style="font-weight: 400;">offer one of the best pricing models</span></a><span style="font-weight: 400;">. GCP does not require upfront payment or a lock-in commitment and offers discount for sustained usage. GCP charges you monthly for on-demand usage of instances by minutes used (minimum of 10 minutes). Google offers a </span><a href="https://cloud.google.com/compute/pricing#sustained_use"><span style="font-weight: 400;">sustained-use</span></a><span style="font-weight: 400;"> discount and publically promised to pass along along to their customers any future price reduction. In contrast, AWS offers several pricing models; on-demand usage priced by the nearest hour, reserved instances &#8211; a commitment based pricing for a specific VM instance, and spot bidding for extra capacity available. Azure offers per minute billing with pay-as-you-go subscriptions, buying from a reseller, and an upfront usage commitment paid in advance or monthly. </span></p>
<p><span style="font-weight: 400;">Let’s talk about services. The array of storage options are impressive: from arbitrary objects (</span><a href="https://cloud.google.com/storage/"><span style="font-weight: 400;">Google Cloud Storage</span></a><span style="font-weight: 400;">), to relational databases (MySql, Sql Server), BigQuery (used by Google Analytics and </span><a href="http://www.snaplogic.com/"><span style="font-weight: 400;">SnapLogic</span></a><span style="font-weight: 400;">), and BigTable ( “NoSql” database used by Google Search and Gmail). You have storage options for cost-efficient data storage based based on frequency of use and the geographic location of your customers.</span></p>
<h3><span style="font-weight: 400;">GCP and .NET</span></h3>
<p><span style="font-weight: 400;">Google also supports .NET technologies like SQL Server, Windows Servers, Visual Studio tools and offers a developer stack featuring IIS, SQL Express and ASP.NET. You can also use Google’s Cloud APIs (with tons of supported libraries), </span><a href="https://cloud.google.com/visual-studio/"><span style="font-weight: 400;">Cloud Tools for Visual Studio</span></a><span style="font-weight: 400;"> and a even work in PowerShell using the </span><a href="https://cloud.google.com/powershell/"><span style="font-weight: 400;">Cloud Tools for PowerShell</span></a><span style="font-weight: 400;"> extension. It is impressive to see that Google is pushing for a more robust .NET environment, with help from people such as </span><a href="https://www.quora.com/Who-is-Jon-Skeet-and-how-did-he-become-famous-on-Stack-Overflow"><span style="font-weight: 400;">Jon Skeet</span></a><span style="font-weight: 400;"> and other notable developers. To learn more, check out this article: </span><a href="https://cloudplatform.googleblog.com/2016/08/making-ASP.NET-apps-first-class-citizens-on-Google-Cloud-Platform.html"><span style="font-weight: 400;">Making ASP.NET apps first-class citizens on Google Cloud Platform.</span></a><span style="font-weight: 400;">  </span></p>
<p><span style="font-weight: 400;">For more details on porting between cloud platforms, using APIs with .NET and other tips, watch for upcoming blogs in this series. </span></p>
<h2><span style="font-weight: 400;">Adoption Costs</span></h2>
<p><span style="font-weight: 400;">There are inherent adoption costs to consider. </span><span style="font-weight: 400;">While all three platforms offer common features like schema-less, NOSQL tables, each has its own flavor: Google’s BigTable vs. Amazon’s DynamoDB vs. Azure’s DocumentDB. They&#8217;re very similar at one level, but not identical. There are <a href="http://db-engines.com/en/system/Amazon+DynamoDB%3BGoogle+Cloud+Bigtable%3BMicrosoft+Azure+DocumentDB">differences in indexing, access and storage structure</a> that can incur migration and training costs. </span></p>
<p><i><span style="font-weight: 400;">“In theory, there is no difference between theory and practice. In practice, there is.”</span></i></p>
<p><span style="font-weight: 400;">On one hand, there might be little new learning if your engineers already know a specific tech stack (e.g. .NET or Java or Node.js). While cloud platforms can be accessed in a variety of programming languages, some implementations are easier to use. Google is growing it’s list of “idiomatic” client libraries that are true to the flavor of each language, particularly .NET. </span></p>
<p><span style="font-weight: 400;">Likewise, infrastructure management operations performed by IT are unique to each platform. Azure has it’s “Blades” web user interface, while AWS and GCP have a more standard web console. As </span><a href="https://blog.falafel.com/author/adam-anderson/"><span style="font-weight: 400;">Adam </span></a><span style="font-weight: 400;">noted in our i</span><a href="https://blog.falafel.com/intro-google-cloud-platform-gcp/"><span style="font-weight: 400;">ntro report on Google Cloud Platform</span></a><span style="font-weight: 400;">, the GCP portal feels like a middle ground between Azure and AWS’s portal: </span></p>
<p><span style="font-weight: 400;">“</span><i><span style="font-weight: 400;">My initial impression is that the GCP portal feels more approachable and snappier than the Azure portal. Another really impressive thing is how Google has really gone all out to make their tooling really accessible directly within the browser.” </span></i></p>
<h2><span style="font-weight: 400;">Hybrid Cloud</span></h2>
<p><span style="font-weight: 400;">Private servers are costly and difficult to scale, as opposed to public clouds. But you may be reluctant to give up private services and storage that are known to work well for critical applications. In this case, you might consider a hybrid cloud environment that uses a mix of public cloud with your own on-premise, private solutions. By moving the workload between the two, you can limit computing needs and manage cost more efficiently. This gives you greater flexibility and more options to deploy data when and where you need it. For example, you could use a cloud provider to host your development environment and less critical data.</span></p>
<h2><span style="font-weight: 400;">Security</span></h2>
<p><span style="font-weight: 400;">Security is one checkbox that no organization can afford to skip. GCP has numerous International Organization for Standardization certifications for its cloud security. The standards serve as assurance that Google has taken specific internal measures to secure its users’ data and protect it from unwanted intruders. </span><a href="https://cloud.google.com/security/compliance"><span style="font-weight: 400;">GCP has the following certifications</span></a><span style="font-weight: 400;">: SSAE16 / ISAE 3402 Type II, ISO 27001, ISO 27017, ISO 27018, FedRamp ATO (Google App Engine), PCI DSS v3.1 and conducts annual audits with an independent auditor. </span></p>
<p>Google also supplies fully integrated <a href="https://cloud.google.com/iam/">Identity and Access Management</a>(IAM) and <a href="https://cloud.google.com/security-scanner/">security scanning</a>.</p>
<h2><span style="font-weight: 400;">What can Falafel do for you?</span></h2>
<p><span style="font-weight: 400;">Falafel’s expertise in .NET is widely known, having worked with the industry’s best companies for many years (See “Great Companies Choose Falafel” on our </span><a href="http://www.falafel.com/"><span style="font-weight: 400;">main page</span></a><span style="font-weight: 400;">). Falafel will be the first Google Cloud Partner on the West Coast to provide GCP solutions for Windows and .NET.</span></p>
<p><span style="font-weight: 400;">Need help to implement and manage the Google Cloud Platform? We can train your staff, work alongside you (mentoring), or simply build the entire solution for you:</span></p>
<ul>
<li style="font-weight: 400;"><span style="font-weight: 400;">Migration Planning &#8211; We work with you to design a strategy that effectively and safely migrates your data to the cloud. </span></li>
<li style="font-weight: 400;"><span style="font-weight: 400;">Migration Execution &#8211; With our expertise and experience, data migration can be done with ease and a peace of mind. Let us move your data for you. </span></li>
<li style="font-weight: 400;"><span style="font-weight: 400;">Compute Engine Configuration &#8211; We can configure multiple virtual machines that your team can access any time. </span></li>
<li style="font-weight: 400;"><span style="font-weight: 400;">End-to-End Solutions &#8211; Our senior engineers have years of experience developing solutions that take full advantage of the flexibility, scalability and cost effective power of the cloud.</span></li>
</ul>
<p><span style="font-weight: 400;">Besides being a GCP .NET cloud implementation service, Falafel will continue to give back to the development community &#8212; watch for our </span><a href="https://blog.falafel.com/"><span style="font-weight: 400;">blog posts</span></a><span style="font-weight: 400;">, guides, ebooks and learning sessions. </span></p>
<h2><span style="font-weight: 400;">Planning for the future</span></h2>
<p><span style="font-weight: 400;">Although Google Cloud Platform is the new entrant to the public cloud space, it offers tons of capability, resources, and competitive pricing that is attractive to businesses considering a move to the cloud or switching from AWS or Azure. Google has put strong emphasis on growing its cloud platform and we will only see improvement from here on. Anticipating the future for your business begins with making the correct business decision. The first step starts here. Why not take a </span><a href="https://console.cloud.google.com/freetrial?_ga=1.30791611.501444976.1480723782&amp;pli=1"><span style="font-weight: 400;">free spin</span></a><span style="font-weight: 400;"> with Google Cloud and see the benefit for yourself?</span></p>
<p><span style="font-weight: 400;">Contact us with any questions or if you need help with your cloud implementation at </span><a href="mailto:support@falafel.com"><span style="font-weight: 400;">support@falafel.com</span></a><span style="font-weight: 400;">. We’re happy to help. </span></p>
<p>The post <a rel="nofollow" href="https://blog.falafel.com/organizations-choose-gcp-business-perspective/">Why Organizations should choose GCP &#8211; A Business Perspective</a> appeared first on <a rel="nofollow" href="https://blog.falafel.com">Falafel Software Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.falafel.com/organizations-choose-gcp-business-perspective/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">6136</post-id>	</item>
	</channel>
</rss>
