tag:blogger.com,1999:blog-10310834631150715862024-02-07T14:46:34.506+11:00Cloudy ShrimpyCloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.comBlogger21125tag:blogger.com,1999:blog-1031083463115071586.post-84928418976078520402022-01-04T19:37:00.003+11:002022-01-04T19:37:14.836+11:00Frontend cross domain communication make easy<p><b>Context</b></p><p class="graf graf--p" name="4614">Building microservice in front-end is getting popular, there is even a <a class="markup--anchor markup--p-anchor" data-href="https://www.manning.com/books/micro-frontends-in-action?a_aid=mfia&a_bid=5f09fdeb" href="https://www.manning.com/books/micro-frontends-in-action?a_aid=mfia&a_bid=5f09fdeb" rel="noopener" target="_blank">book</a> about it.</p><p class="graf graf--p" name="3c45">If you are building a front-end platform for public or internally for your company, most likely you will encounter the need to enable multiple teams to develop and release in parallel. To ensure productivity, your platform should provide solution for isolated team code base as well as release pipeline.</p><p class="graf graf--p" name="a2cd">Which means the final product that present to end users will be a master website loads a bunch of other websites into its DOM. In order to provide enough security and avoid one sub app crash the entire website, you will have to use iframe as the container, as Web Component is far from mature.</p><p class="graf graf--p" name="53cf">One of the major issue with iframe is, communicate over the boundary is a huge pain. As “postMessage” API is like UDP, it is very hard and cumbersome even just exchange some simple text.</p><h3 class="graf graf--h3 graf--startsWithDoubleQuote" name="cba2">“Bridge” for the rescue</h3><p class="graf graf--p" name="4134">I created an open source package <a class="markup--anchor markup--p-anchor" data-href="https://github.com/shrimpy/bridge" href="https://github.com/shrimpy/bridge" rel="noopener" target="_blank">Bridge</a>, to provide developer friendly protocols for developer to easily communicate across boundary.</p><h3 class="graf graf--h3" name="4ba3">Expose an function/API</h3><p class="graf graf--p" name="b946">When you want to expose a function/API for others to invoke, similar to a backend API, with Bridge we just have to create a resolver and have your API as a function inside it.</p><pre class="graf graf--pre" name="9686"><code class="markup--code markup--pre-code">// Here is a sample resolver that expose an "echo" API</code></pre><pre class="graf graf--pre" name="04d5"><code class="markup--code markup--pre-code">class HostSampleResolver implements IResolver {<br /> public name: string = "HostSampleResolver";<br /><br /> public echo(inputs: { message: string }, from: string): Promise<any> {<br /> return new Promise((resolver) => {<br /> setTimeout(() => {<br /> resolver({ data: `echo from host: ${inputs.message}` });<br /> }, 500);<br /> });<br /> }<br />}</code></pre><p class="graf graf--p" name="4439">To invoke above API, all your need is one function call. Name the resolver we want to invoke, the API we want to call, and pass in an input if there is any.</p><pre class="graf graf--pre" name="e6d3">const response = await client.invokeResolver<string>("HostSampleResolver", "echo", { message: "message from client" });</pre><h3 class="graf graf--h3" name="9751">Subscribe to an event</h3><p class="graf graf--p" name="6c74">Bridge also supports pub-sub. Simply subscribe to an event that the other side might push over any notification.</p><pre class="graf graf--pre" name="6a64">client.subscribe("host-event", (inputs: any) => {</pre><pre class="graf graf--pre" name="e526"> console.log("Client - sub ===>", inputs);</pre><pre class="graf graf--pre" name="4928">});</pre><p class="graf graf--p" name="46f7">To push notification to subscriber is just one function away</p><pre class="graf graf--pre" name="2ac3">host.broadcastEvent(`host-event`, "YOLO");</pre><h3 class="graf graf--h3" name="837e">Get your hand dirty</h3><p class="graf graf--p" name="c1f5">You can look at the full and runnable sample code from <a class="markup--anchor markup--p-anchor" data-href="https://github.com/shrimpy/bridge/tree/main/example" href="https://github.com/shrimpy/bridge/tree/main/example" rel="noopener" target="_blank">Bridge’s repository</a>. To run it, please follow instructions from <a class="markup--anchor markup--p-anchor" data-href="https://github.com/shrimpy/bridge#how-to-run-the-example" href="https://github.com/shrimpy/bridge#how-to-run-the-example" rel="noopener" target="_blank">README.md</a></p><p class="graf graf--p" name="0e7c">Here is a preview on what you will expect from our sample, where we have a website loads another website into a DIV as well as an IFRAME, and both sub-apps from the DIV and the IFRAME are communicating with the master website via Bridge.</p><figure class="graf graf--figure" name="f396"><img class="graf-image" data-height="961" data-image-id="1*GprgLbpeMKQ-qjNFUDCtgg.png" data-is-featured="true" data-width="1793" src="https://cdn-images-1.medium.com/max/800/1*GprgLbpeMKQ-qjNFUDCtgg.png" /></figure><h3 class="graf graf--h3" name="538d">Enjoy!</h3><div>https://shrimpy.medium.com/frontend-cross-domain-communication-make-easy-c91fcdb6fb5d</div>Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com0tag:blogger.com,1999:blog-1031083463115071586.post-33176822089280901712015-05-01T11:38:00.001+10:002015-05-01T11:42:32.514+10:00Deploy your Go app onto Azure App Services (Websites) in ease<h3>
Try it:</h3>
Click <a href="https://deploy.azure.com/?repository=https://github.com/shrimpy/gotry#/form/setup" target="_blank">this link</a>, you will deploy a sample Go web app onto your Azure subscription<br />
<br />
<h3>
Details:</h3>
Azure App Services now supports Go 1.4.2 with <a href="http://azure.microsoft.com/en-us/documentation/articles/web-sites-publish-source-control/" target="_blank">continues deployment</a>. Once continues deployment is setup, every time you push code to your continues deployment branch, a new deployment will be trigger.<br />
<br />
if you read the deployment log detaily, you will notice that Azure will create a Go workspace in temp folder, then copy your code to src\azureapp, build against azureapp folder and produce an "azureapp.exe".<br />
<br />
Last, it generate a web.config and use HttpPlatformHandler to run your Go app.<br />
<br />
<b>Restriction:</b><br />
<br />
<ul>
<li>Have to place main package at the root of your app</li>
<li>Currently only support Go 1.4.2, no able to select a specific Go version yet</li>
</ul>
<br />
<br />
<i>Sample Go app:</i><br />
<a href="https://github.com/shrimpy/gotry">https://github.com/shrimpy/gotry</a><br />
<br />
<i>Sample Deployment Log:</i><br />
<i><br /></i>
<br />
<pre>Handling Go deployment.
Prepare workspace
GOROOT D:\Program Files\go\1.4.2
Creating GOPATH\bin D:\local\Temp\30a88a27-1ce2-49ef-b1b8-6f32716c9652\gopath\bin
Creating GOPATH\pkg D:\local\Temp\30a88a27-1ce2-49ef-b1b8-6f32716c9652\gopath\pkg
Creating GOPATH\src D:\local\Temp\30a88a27-1ce2-49ef-b1b8-6f32716c9652\gopath\src
Creating D:\local\Temp\30a88a27-1ce2-49ef-b1b8-6f32716c9652\gopath\src\azureapp
Copy source code to Go workspace
-------------------------------------------------------------------------------
ROBOCOPY :: Robust File Copy for Windows
-------------------------------------------------------------------------------
Started : Thursday, April 30, 2015 5:52:54 PM
Source : D:\home\site\repository\
Dest : D:\local\Temp\30a88a27-1ce2-49ef-b1b8-6f32716c9652\gopath\src\azureapp\
Files : *.*
Exc Files : .deployment
deploy.cmd
Exc Dirs : .git
.hg
Options : *.* /NDL /NFL /S /E /DCOPY:DA /COPY:DAT /NP /R:1000000 /W:30
------------------------------------------------------------------------------
------------------------------------------------------------------------------
Total Copied Skipped Mismatch FAILED Extras
Dirs : 3 1 1 0 0 0
Files : 13 13 0 0 0 0
Bytes : 19.4 k 19.4 k 0 0 0 0
Times : 0:00:00 0:00:00 0:00:00 0:00:00
Speed : 182743 Bytes/sec.
Speed : 10.456 MegaBytes/min.
Ended : Thursday, April 30, 2015 5:52:54 PM
Resolving dependencies
Building Go app to produce exe file
Copy files for deployment
KuduSync.NET from: 'D:\home\site\repository' to: 'D:\home\site\wwwroot'
Deleting file: 'hostingstart.html'
Copying file: 'azureapp.exe'
Copy web.config
1 file(s) copied.
Finished successfully.
</pre>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<o:p></o:p></div>
<br />
<div style="background: white;">
<o:p></o:p></div>
<div style="background: white;">
<br /></div>
Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com2tag:blogger.com,1999:blog-1031083463115071586.post-31307555306609687872015-04-16T17:17:00.006+10:002015-05-01T11:42:15.930+10:00Running Go web app on Azure App Services (Websites) with custom deployment script<h3>
Short version:</h3>
<br />
Perform a <a href="http://azure.microsoft.com/en-us/documentation/articles/web-sites-publish-source-control/">continues deployment</a> with code from this <a href="https://github.com/shrimpy/gotry">repo</a> to your Azure Website. Once deploy, you should be able to see below result, a perfect test web app that use Go "<span style="background-color: white; color: #183691; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; line-height: 16.7999992370605px; white-space: pre;">net/http</span>" package, <a href="https://github.com/gin-gonic/gin">Gin</a> and <a href="https://github.com/go-martini/martini">Martini </a>all together.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2LDAajN_Ldpgljd-HwLgD0KRiIvWex1zglBrlB5HUXe4VBUNC1KDTjhyrhli_V29410azmA2xAZsnVKrYw-f0oOj4jGVSHP_nk5WGuR-GHFZrIV7Oy9gHV3rJ_8zo2EjDcHeuH4BTTjto/s1600/GoTry.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2LDAajN_Ldpgljd-HwLgD0KRiIvWex1zglBrlB5HUXe4VBUNC1KDTjhyrhli_V29410azmA2xAZsnVKrYw-f0oOj4jGVSHP_nk5WGuR-GHFZrIV7Oy9gHV3rJ_8zo2EjDcHeuH4BTTjto/s1600/GoTry.png" height="292" width="400" /></a></div>
<br />
<br />
<h3>
<b>Behind the scenes:</b></h3>
<br />
The core is to understand <a href="https://github.com/shrimpy/gotry/blob/master/GoDeploy.cmd">GoDeploy.cmd</a> script from repo, below are the key concepts:<br />
<br />
<b>To run Go app:</b><br />
Create a web.config as below. If you build your go app (exe file), all you need is upload your exe file and update web.config file to reference to it.<br />
<br />
<pre class="brush: xml"><configuration>
<system .webserver="">
<handlers>
<add modules="httpPlatformHandler" name="httpplatformhandler" path="*" resourcetype="Unspecified" verb="*">
</add></handlers>
<httpplatform processpath="D:\home\site\wwwroot\azureapp.exe" startuptimelimit="60">
</httpplatform>
</system>
</configuration>
</pre>
<b><br /></b>
<b><br /></b>
<b>To build:</b><br />
<br />
GOROOT:<br />
There is no GOROOT environment variable yet, but the binary is reside in "<span style="background-color: white; color: #333333; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; line-height: 16.7999992370605px; white-space: pre;">D:\Program Files\Go\1.4.2</span>". define your own GOROOT and point to it<br />
<br />
<a href="https://github.com/shrimpy/gotry/blob/master/GoDeploy.cmd">Build Script</a>:<br />
<br />
<ul>
<li> Create workspace and config GOPATH point to it</li>
</ul>
<br />
workspace:<br />
{folder}/src<br />
{folder}/bin<br />
{folder}/pkg<br />
<br />
<pre class="brush: bash"> ECHO creating %GOPATH%\bin
MKDIR "%GOPATH%\bin"
ECHO creating %GOPATH%\pkg
MKDIR "%GOPATH%\pkg"
ECHO creating %GOPATH%\src
MKDIR "%GOPATH%\src"
</pre>
<br />
<br />
<ul>
<li>Create app folder under "{folder}/src", and copy source code into it</li>
</ul>
<div>
<pre class="brush: bash">ECHO creating %GOAZUREAPP%
MKDIR %GOAZUREAPP%
ECHO copying sourc code to %GOAZUREAPP%
CP gotry.go %GOAZUREAPP%
</pre>
<pre></pre>
</div>
<ul>
<li>Resolve dependencies and build</li>
</ul>
<div>
<pre class="brush: bash">ECHO Resolving dependencies
CD "%GOPATH%\src"
%GOEXE% get %FOLDERNAME%
ECHO Building ...
%GOEXE% build -o %WEBROOT_PATH%\%FOLDERNAME%.exe %FOLDERNAME%</pre>
</div>
Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com0tag:blogger.com,1999:blog-1031083463115071586.post-54518298187664355912012-01-30T18:45:00.000+11:002012-01-30T18:45:39.556+11:00Windows Azure Storage MapperOpen source project: <a href="http://azuredbmapper.codeplex.com/">http://azuredbmapper.codeplex.com/</a><br />
The StorageClient library API is not that easy while you try to understand how the REST API is working for you.<br />
<br />
Here I created an Azure Storage Mapper, which is purelly expose the REST API.<br />
All what you read from MSDN about REST API, you will find it in Azure Storage Mapper.<br />
Same wording, same way to use. Give you the very native feeling of Azure Storage.<br />
<br />
Right now only support Table Storage... Blob Storage and Queue Storage is coming soon ...Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com0tag:blogger.com,1999:blog-1031083463115071586.post-25375038574047293492010-12-10T18:19:00.003+11:002010-12-18T21:54:03.411+11:00How to run Ruby On Rails on Google AppEngineThere is a tutorial <a href="https://gist.github.com/671792">https://gist.github.com/671792</a> by John Woodell,<br />
however it was costumed running in linux environment,<br />
and there is some slightly changes they didnt update their tutorial script,<br />
the script will not work out of box, <br />
So in here i am making a post, especially benefit users who is using Windows, since i am doing this in Windows 7 environment.<br />
<br />
PS : i assume u have already had a google app engine account, if u dont, do some bing or google and get one <br />
<br />
Specially thanks for the help from Andrew Myers.<br />
<br />
1) Install Java Development Kit 6 (JDK6)<br />
make sure you have similar stuff show up in your windows command prompt<br />
<br />
<blockquote>>java -version<br />
java version "1.6.0_21"<br />
Java(TM) SE Runtime Environment (build 1.6.0_21-b07)<br />
Java HotSpot(TM) Client VM (build 17.0-b17, mixed mode, sharing)<br />
>javac -version<br />
javac 1.6.0_21</blockquote><br />
2) Install AppEngine Java SDK <a href="http://code.google.com/appengine/downloads.html">http://code.google.com/appengine/downloads.html</a><br />
Download the SDK, and make sure you put the "bin" directory into your system "Path"<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisdKtrtJe-j8QG22AGXDdRyFYNhon1PwgPsF_kOxsF4FvBuWFZjwjYnjYJGkxB6yT43thyPisSksKErom802IJ9LShKSJ_dgH0N1lkgtHWpkdl1awF33G8gYX4GSZuMlomojLLcbrlmw7K/s1600/APP_ENGINE_PATH.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisdKtrtJe-j8QG22AGXDdRyFYNhon1PwgPsF_kOxsF4FvBuWFZjwjYnjYJGkxB6yT43thyPisSksKErom802IJ9LShKSJ_dgH0N1lkgtHWpkdl1awF33G8gYX4GSZuMlomojLLcbrlmw7K/s1600/APP_ENGINE_PATH.png" /></a></div><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
3) Install Ruby 1.8.7 , not JRuby<br />
Download it <a href="http://www.ruby-lang.org/en/downloads/">http://www.ruby-lang.org/en/downloads/</a>, and install it,<br />
make sure you associate *.rb to be run by ruby (for windows install, there is the check box)<br />
<br />
again open a new command prompt, you should have something like this<br />
<blockquote><br />
>ruby -v<br />
ruby 1.8.7 (2010-08-16 patchlevel 302) [i386-mingw32]<br />
>gem -v<br />
1.3.7</blockquote><br />
4) Install plugins for ruby<br />
Make sure you open a command prompt as administrator<br />
<br />
and type in the following one by one<br />
<br />
<blockquote>gem install google-appengine<br />
<pre>gem install rails -v "2.3.10"</pre><pre>gem install rails_dm_datastore</pre><pre>gem install activerecord-nulldb-adapter</pre></blockquote><br />
each one will take a while, so be patient..<br />
<br />
5) Make a directory to contain you ROR application<br />
<blockquote>mkdir railsv1<br />
cd railsv1</blockquote>Or you can use GUI to do it.<br />
<br />
6) Copy the code below, save it to a file, for example rails2310_appengine.rb<br />
<br />
#!/usr/bin/ruby<br />
#<br />
# Copyright:: Copyright 2009 Google Inc.<br />
# Original Author:: John Woodell (mailto:woodie@google.com)<br />
#<br />
# Licensed under the Apache License, Version 2.0 (the "License");<br />
# you may not use this file except in compliance with the License.<br />
# You may obtain a copy of the License at<br />
#<br />
# http://www.apache.org/licenses/LICENSE-2.0<br />
#<br />
# Unless required by applicable law or agreed to in writing, software<br />
# distributed under the License is distributed on an "AS IS" BASIS,<br />
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<br />
# See the License for the specific language governing permissions and<br />
# limitations under the License.<br />
<br />
require 'fileutils'<br />
require 'open-uri'<br />
<br />
def composite(source, fragment, index = nil, trim = nil)<br />
File.open(source, 'r+') do |f|<br />
lines = f.readlines<br />
lines = lines[0..trim] unless trim.nil?<br />
f.pos = 0<br />
File.open(fragment) do |z|<br />
section = z.readlines<br />
if index and index.size < lines.size<br />
f.print lines[0,index] + section + lines[index..-1]<br />
else <br />
f.print lines + section<br />
end<br />
end<br />
f.truncate(f.pos)<br />
end <br />
FileUtils.rm fragment<br />
end<br />
<br />
def download_file(path, url)<br />
open(url) do |r|<br />
FileUtils.mkpath(File.dirname(path))<br />
open(path,"w"){|f| f.write(r.read) }<br />
end<br />
end<br />
SET_CMD = RUBY_PLATFORM.include?('mswin32') ? 'set' : 'export'<br />
MORE_GEMS = 'rails_appengine/active_support_vendored'<br />
FILE_BASE = 'http://appengine-jruby.googlecode.com/hg/demos/rails2/'<br />
MOD_FILES = %w{ app/controllers/rails/info_controller.rb public/favicon.ico<br />
config.ru config/boot_rb config/environment_rb<br />
config/initializers/gae_init_patch.rb config/database.yml<br />
script/console.sh script/publish.sh script/server.sh }<br />
# Install Rails 2.3.10<br />
FileUtils.touch 'config.ru'<br />
gemsrc = ARGV[0].eql?('tiny_ds') ? 'Gemfile_td' : 'Gemfile'<br />
download_file("Gemfile", "#{FILE_BASE}#{gemsrc}")<br />
download_file("gems_2310", "#{FILE_BASE}gems_2310")<br />
composite('Gemfile', 'gems_2310', nil, -2)<br />
FileUtils.mkdir_p 'WEB-INF'<br />
download_file("WEB-INF/app.yaml", "#{FILE_BASE}WEB-INF/app.yaml")<br />
system 'appcfg.rb bundle --update .'<br />
# Remove dups and generate Rails app<br />
# Generate rails, and skip APIs to escape the shell<br />
system "rails _2.3.10_ ."<br />
# Fetch configuration files<br />
FileUtils.mkdir_p 'app/controllers/rails'<br />
MOD_FILES.each { |path| download_file(path, "#{FILE_BASE}#{path}") }<br />
if ARGV[0].eql? 'tiny_ds'<br />
download_file("config/environment_rb", "#{FILE_BASE}config/environment_td")<br />
end<br />
# Merge configs into boot.rb<br />
composite('config/boot.rb', 'config/boot_rb', 108)<br />
# Merge configs into environment.rb<br />
composite('config/environment.rb', 'config/environment_rb', 30)<br />
# install the nulldb adapter<br />
system 'ruby script/plugin install http://svn.avdi.org/nulldb/trunk/'<br />
puts "##"<br />
puts "## Now type 'dev_appserver.rb .'" <br />
puts "##"<br />
<br />
<br />
and run it, e.g ruby rails2310_appengine.rb, then you should see something like this:<br />
<br />
<a name='more'></a><br />
<br />
railsv1>ruby rails2310_appengine.rb<br />
exists<br />
create app/controllers<br />
create app/helpers<br />
create app/models<br />
create app/views/layouts<br />
create config/environments<br />
create config/initializers<br />
create config/locales<br />
create db<br />
create doc<br />
create lib<br />
create lib/tasks<br />
create log<br />
create public/images<br />
create public/javascripts<br />
create public/stylesheets<br />
create script/performance<br />
create test/fixtures<br />
create test/functional<br />
create test/integration<br />
create test/performance<br />
create test/unit<br />
create vendor<br />
create vendor/plugins<br />
create tmp/sessions<br />
create tmp/sockets<br />
create tmp/cache<br />
create tmp/pids<br />
create Rakefile<br />
create README<br />
create app/controllers/application_controller.rb<br />
create app/helpers/application_helper.rb<br />
create config/database.yml<br />
create config/routes.rb<br />
create config/locales/en.yml<br />
create db/seeds.rb<br />
create config/initializers/backtrace_silencers.rb<br />
create config/initializers/inflections.rb<br />
create config/initializers/mime_types.rb<br />
create config/initializers/new_rails_defaults.rb<br />
create config/initializers/session_store.rb<br />
create config/initializers/cookie_verification_secret.rb<br />
create config/environment.rb<br />
create config/boot.rb<br />
create config/environments/production.rb<br />
create config/environments/development.rb<br />
create config/environments/test.rb<br />
create script/about<br />
create script/console<br />
create script/dbconsole<br />
create script/destroy<br />
create script/generate<br />
create script/runner<br />
create script/server<br />
create script/plugin<br />
create script/performance/benchmarker<br />
create script/performance/profiler<br />
create test/test_helper.rb<br />
create test/performance/browsing_test.rb<br />
create public/404.html<br />
create public/422.html<br />
create public/500.html<br />
create public/index.html<br />
create public/favicon.ico<br />
create public/robots.txt<br />
create public/images/rails.png<br />
create public/javascripts/prototype.js<br />
create public/javascripts/effects.js<br />
create public/javascripts/dragdrop.js<br />
create public/javascripts/controls.js<br />
create public/javascripts/application.js<br />
create doc/README_FOR_APP<br />
create log/server.log<br />
create log/production.log<br />
create log/development.log<br />
create log/test.log<br />
+ ./LICENSE<br />
+ ./README<br />
+ ./Rakefile<br />
+ ./init.rb<br />
+ ./lib/active_record/connection_adapters/nulldb_adapter.rb<br />
+ ./lib/nulldb_rspec.rb<br />
+ ./spec/nulldb_spec.rb<br />
+ ./tasks/database.rake<br />
##<br />
## Now type 'dev_appserver.rb .'<br />
##<br />
<br />
7) Great, we are almost there, type 'dev_appserver.rb .' to your command prompt<br />
<br />
<blockquote>railsv1>dev_appserver.rb .<br />
=> Bundling gems<br />
Calculating dependencies...<br />
Updating source: http://gems.rubyforge.org<br />
d:/Ruby187/lib/ruby/gems/1.8/gems/bundler08-0.8.5/lib/bundler08/resolver.rb:115:Warning: Gem::Dependency#version_require<br />
ments is deprecated and will be removed on or after August 2010. Use #requirement<br />
Caching: actionmailer-2.3.10.gem<br />
Caching: actionpack-2.3.10.gem<br />
Caching: activerecord-2.3.10.gem<br />
Caching: activeresource-2.3.10.gem<br />
Caching: activesupport-2.3.10.gem<br />
Downloading addressable-2.2.2.gem<br />
Caching: appengine-apis-0.0.22.gem<br />
Caching: appengine-rack-0.0.12.gem<br />
Downloading bouncy-castle-java-1.5.0145.2.gem<br />
Downloading dm-appengine-0.1.3.gem<br />
Downloading dm-ar-finders-1.0.2.gem<br />
Downloading dm-core-1.0.2.gem<br />
Downloading dm-timestamps-1.0.2.gem<br />
Downloading dm-validations-1.0.2.gem<br />
Downloading extlib-0.9.15.gem<br />
Caching: jruby-jars-1.5.6.gem<br />
Downloading jruby-openssl-0.7.2.gem<br />
Caching: jruby-rack-1.0.4.gem<br />
Downloading lexidecimal-0.0.1.gem<br />
Caching: rack-1.1.0.gem<br />
Caching: rails-2.3.10.gem<br />
Downloading rails_appengine-0.0.6.gem<br />
Downloading rails_dm_datastore-0.2.16.gem<br />
Caching: rake-0.8.7.gem<br />
Installing activesupport (2.3.10)<br />
Installing extlib (0.9.15)<br />
Installing actionmailer (2.3.10)<br />
Installing lexidecimal (0.0.1)<br />
Installing rails_appengine (0.0.6)<br />
Installing bouncy-castle-java (1.5.0145.2)<br />
Installing dm-timestamps (1.0.2)<br />
Installing rack (1.1.0)<br />
Installing actionpack (2.3.10)<br />
Installing jruby-jars (1.5.6)<br />
Installing jruby-openssl (0.7.2)<br />
Installing dm-validations (1.0.2)<br />
Installing rake (0.8.7)<br />
Installing addressable (2.2.2)<br />
Installing dm-core (1.0.2)<br />
Installing dm-appengine (0.1.3)<br />
Installing jruby-rack (1.0.4)<br />
Installing appengine-rack (0.0.12)<br />
Installing appengine-apis (0.0.22)<br />
Installing activerecord (2.3.10)<br />
Installing dm-ar-finders (1.0.2)<br />
Installing rails_dm_datastore (0.2.16)<br />
Installing activeresource (2.3.10)<br />
Installing rails (2.3.10)<br />
Done.<br />
=> Packaging gems<br />
=> Installing appengine-api-1.0-sdk-1.4.0.jar<br />
=> Installing appengine-api-labs-1.4.0.jar<br />
=> Installing appengine-rack.jar<br />
=> Installing bcmail-jdk15-145.jar<br />
=> Installing bcprov-jdk15-145.jar<br />
=> Installing jruby-core-1.5.6.jar<br />
=> Installing jruby-stdlib-1.5.6.jar<br />
=> Installing jopenssl.jar<br />
=> Installing jruby-rack-1.0.4.jar<br />
=> Booting DevAppServer<br />
=> Press Ctrl-C to shutdown server<br />
10/12/2010 6:44:02 AM com.google.apphosting.utils.jetty.JettyLogger info<br />
INFO: Logging to JettyLogger(null) via com.google.apphosting.utils.jetty.JettyLogger<br />
10/12/2010 6:44:07 AM com.google.apphosting.utils.config.AppEngineWebXmlReader readAppEngineWebXml<br />
INFO: Successfully processed E:\xiaomin\projects\appengine-ror\railsv1\WEB-INF/appengine-web.xml<br />
10/12/2010 6:44:07 AM com.google.apphosting.utils.config.AbstractConfigXmlReader readConfigXml<br />
INFO: Successfully processed E:\xiaomin\projects\appengine-ror\railsv1\WEB-INF/web.xml<br />
10/12/2010 6:44:07 AM com.google.apphosting.utils.jetty.JettyLogger info<br />
INFO: jetty-6.1.x<br />
10/12/2010 6:44:39 AM com.google.apphosting.utils.jetty.JettyLogger info<br />
INFO: Started SelectChannelConnector@127.0.0.1:8080<br />
10/12/2010 6:44:39 AM com.google.appengine.tools.development.DevAppServerImpl start<br />
INFO: The server is running at http://localhost:8080/</blockquote><br />
8) Finally, go to your browser, and enjoy yourself for your first app-engine ROR, <br />
<blockquote><a href="http://localhost:8080/">http://localhost:8080</a></blockquote><br />
9) We are not done yet, now it is running on your local machine,<br />
we are just one step a way to have a app up in the cloud.<br />
<br />
Let go to your Google AppEngine account<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZZlAshKJGmeN3l1uhrO4rgPBl9xy5pyUNO3_TvMqtb6YaF5J3e4RWy-f_u086jGKLRbWJRtLNKjNIBjvxc_iQsLI1pqPRZ5iOw28De1uod33qNz_jm05IdxSJCfjlQ2-S06vhcPncM48B/s1600/shrimpyAppEngineAccount.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZZlAshKJGmeN3l1uhrO4rgPBl9xy5pyUNO3_TvMqtb6YaF5J3e4RWy-f_u086jGKLRbWJRtLNKjNIBjvxc_iQsLI1pqPRZ5iOw28De1uod33qNz_jm05IdxSJCfjlQ2-S06vhcPncM48B/s1600/shrimpyAppEngineAccount.png" /></a></div><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Copy the name of your application, in my case it is "fancyshrimpy" ... what a great name...<br />
<br />
10) Edit configure file, and put your application name attach to your app which u had just created<br />
<br />
>railsv1\WEB-INF\app.yaml<br />
at the very first line, put your application name there (they call it application-id)<br />
application: fancyshrimpy<br />
<br />
11) finally type "appcfg.rb update ."<br />
<br />
you will have something like this:<br />
<br />
railsv1>appcfg.rb update .<br />
=> Running AppCfg<br />
Reading application configuration data...<br />
10/12/2010 5:57:00 PM com.google.apphosting.utils.config.AppEngineWebXmlReader readAppEngineWebXml<br />
INFO: Successfully processed .\WEB-INF/appengine-web.xml<br />
10/12/2010 5:57:00 PM com.google.apphosting.utils.config.AbstractConfigXmlReader readConfigXml<br />
INFO: Successfully processed .\WEB-INF/web.xml<br />
Beginning server interaction for fancyshrimpy...<br />
0% Creating staging directory<br />
5% Scanning for jsp files.<br />
20% Scanning files on local disk.<br />
25% Initiating update.<br />
Email: xxxxxxxx@gmail.com<br />
Password for xxxxxxxx@gmail.com:<br />
28% Cloning 7 static files.<br />
31% Cloning 57 application files.<br />
40% Uploading 6 files.<br />
52% Uploaded 1 files.<br />
61% Uploaded 2 files.<br />
68% Uploaded 3 files.<br />
73% Uploaded 4 files.<br />
77% Uploaded 5 files.<br />
80% Uploaded 6 files.<br />
82% Initializing precompilation...<br />
90% Deploying new version.<br />
95% Will check again in 1 seconds.<br />
98% Will check again in 2 seconds.<br />
99% Will check again in 4 seconds.<br />
99% Will check again in 8 seconds.<br />
99% Closing update: new version is ready to start serving.<br />
99% Uploading index definitions.<br />
<br />
Update completed successfully.<br />
Success.<br />
Cleaning up temporary files...<br />
<br />
Now the very end, go to your app and play with it...<br />
<a href="http://fancyshrimpy.appspot.com/env.html">http://fancyshrimpy.appspot.com/env.html</a><br />
<br />
End..Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com2tag:blogger.com,1999:blog-1031083463115071586.post-86006993441905442312010-07-16T13:19:00.004+10:002010-07-20T14:26:39.608+10:00When pervasive computing meet cloud computing, Infinite VS InfiniteRecently i am trying to propose a project base on my <a href="http://cloudyshrimpy.blogspot.com/2010/04/cloud-computing-it-management-home.html">previous idea</a>, of course a lot more detail than the pose, for my PhD study project. Now i am crazily reading papers from all kinds of area, Internet of Things, Pervasive Computing, Cloud Computing, try to identical the research value in my project.<br />
<br />
Today just want to share some interesting finding during my reading.<br />
<br />
In one paper "Pervasive commuting a paradigm for the 21st century" by Debasbis saba and Amitava Mukberjee. In the issues and challenges they mentioned,<br />
<br />
<i>"Though pervasive computing components are already deployed in many environments, integrating them into a single platform is still a research problem. The problem is similar to what researchers in distributed computing face, but the scale is bigger,. As the number of devices and applications increases, integration becomes more complex. For example, servers must handle thousands of concurrent client connections, and the influx of pervasive devices would quickly approach the host`s capacities. We need a confederation of autonomous servers cooperating to provide user services."</i><br />
<br />
And as what we know from cloud computing, we can ask/rent as much as computing resource we want to deal with our need.<br />
<br />
If a auto-scale framework/model with a multi tenancy architecture application can be created base on cloud computing, sounds like the issue mention in the paper will be easily solved.<br />
<br />
And imaging if there is a standard that can build into all electric appliances, and there is a router like agent that can collect information/send control signal from/to those electric appliances, and process all these information in the multi tenancy architecture application up in the cloud, such kind of project will absolutely benefit human being a lot than we can expected<br />
<br />
More, some of the projects <a href="http://www.blogger.com/">demo</a> in <a href="http://www.blogger.com/">Oxygen MIT</a> can be easily achieve without creating any new technologies as well.Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com1tag:blogger.com,1999:blog-1031083463115071586.post-70537278098849457982010-05-06T05:13:00.002+10:002010-05-06T05:14:34.017+10:00Relation Decoupling -- Migrate from Relational Database to Non Relational Cloud Database<span style="font-size: x-large;"><b>Issue </b></span><br />
<br />
<span style="font-size: large;">Relation decoupling problem </span><br />
<br />
<div class="separator" style="clear: both; text-align: center;"></div><br />
When doing the migration, there are lots of complex join/ cross table selection query, or views which implemented by such kind of query<br />
<br />
<br />
<span style="font-size: x-large;"><b>Possible solution:</b></span><br />
<br />
<br />
1) To migrate such kind of data, seems we need to re-model the database, get rid of the relation in the database, and move these kind of logic to be application logic (code implementation).<br />
<br />
<br />
Similar to Ruby On Rails, they handle all the relation in coding logic, database level relation is not a must.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjygpe8g8h4CLEAhb8EE4zm89y-r7Y4Ii6PXKqiW3dbcR_0AQfj4oxfQRnL42qlQu_jjm5zSyU_2lcbk4gWOy83skHBwZlqFHDSb73NrxJeWVuu0s6VwrrFzs04bRxm831jGSkbND6Ttj8h/s1600/1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjygpe8g8h4CLEAhb8EE4zm89y-r7Y4Ii6PXKqiW3dbcR_0AQfj4oxfQRnL42qlQu_jjm5zSyU_2lcbk4gWOy83skHBwZlqFHDSb73NrxJeWVuu0s6VwrrFzs04bRxm831jGSkbND6Ttj8h/s400/1.png" width="400" /></a></div><br />
<br />
2) Pre-Process relation, and keep all these result in database, when certain query come, server can return data right away.<br />
<br />
<br />
This approach looks like some kind of data warehouse. Which might only suitable for application only do read action mostly.<br />
<br />
<br />
But it doesn`t mean we cannot do write action.<br />
<br />
We can ask the application direct request to another server which particularly design for writing data.<br />
<br />
<br />
The only drawback is that, the result might not be able to display in a instance manner. It depends on how agile my “Process Engine” can be.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhB2SYkVyl3U2-cY2cVHEwTB806ThlO_w3P0eZCnIY49m2ieGCBJRen7mHN7uhw5miPeyZSqZqbEQgVTdLbKVu3NkX-S9PfbIJmMn6S5P_3oXx0HXKk8GxAIVgfpFbqxlWltv__7HW55neL/s1600/11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="210" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhB2SYkVyl3U2-cY2cVHEwTB806ThlO_w3P0eZCnIY49m2ieGCBJRen7mHN7uhw5miPeyZSqZqbEQgVTdLbKVu3NkX-S9PfbIJmMn6S5P_3oXx0HXKk8GxAIVgfpFbqxlWltv__7HW55neL/s400/11.png" width="400" /></a></div>Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com0tag:blogger.com,1999:blog-1031083463115071586.post-41389498082646106082010-04-22T04:56:00.001+10:002010-04-22T04:57:14.714+10:00A Peek at Multitenancy in Azure Table StroageAs we know, the programming model for using Windows Azure Table Storage is like the pic below<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3LHbSe7OqrVqnWPfows_sLfpanOyWCe2A_S_q3Zbuek5m_ITwCEn06ZumYMIFc5eD6CgCFVvykC6s6Fo9VqCtEsQNLoR0YSvehv8U8nmitrMUuoIeXF4-Elf4RewQ3Y5oALDw1GBvSpvx/s1600/1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3LHbSe7OqrVqnWPfows_sLfpanOyWCe2A_S_q3Zbuek5m_ITwCEn06ZumYMIFc5eD6CgCFVvykC6s6Fo9VqCtEsQNLoR0YSvehv8U8nmitrMUuoIeXF4-Elf4RewQ3Y5oALDw1GBvSpvx/s400/1.png" width="400" /></a></div><br />
<br />
Every table can be partition base on custom Partition Key.<br />
If we take the advantage of the Partition Key, we can easily create a multitenancy data struture.<br />
<br />
For example, we want to create a multi user blog, just like blogger, we might have a table, call it "Posts", to store the post written by the users.<br />
Obviously, we can use the username as Partition Key.<br />
So base on the username, we can easily retrieve the corresponding set of data.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqqCKD7w92m-c82X6J4jOjqSbNqEQnT1ZLmdwZMTyXZHyRZCsj_FSW_sukeRjuJOIoSPkpzan8BTfTH6Ot6FcdINCzDREzOL8d3Jb9c9ccnKr1Ej8SLcNaIw5JXBWhP9nw2s2GhJIdVtQl/s1600/2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="242" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqqCKD7w92m-c82X6J4jOjqSbNqEQnT1ZLmdwZMTyXZHyRZCsj_FSW_sukeRjuJOIoSPkpzan8BTfTH6Ot6FcdINCzDREzOL8d3Jb9c9ccnKr1Ej8SLcNaIw5JXBWhP9nw2s2GhJIdVtQl/s400/2.png" width="400" /></a></div><br />
<br />
This kind of approach, data level multitenacy architecture, should be exist long time ago, but apply them onto cloud storage, will gain benefit that we cannot have in relational database.<br />
<br />
Cloud storage will guarantee all data be stored highly distributed, and fully replicated.Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com0tag:blogger.com,1999:blog-1031083463115071586.post-5629692828050841982010-04-01T05:16:00.017+11:002010-04-01T12:52:06.005+11:00Cloud computing + IT management = Home AutomationI just have something in my mind that, there will be soon or already become real for some of the area, everything will be or has been able to connect internet.<br /><br />And when talking about IT management, usually we will think of enterprise, company or education institute, when they are up to a certain size, they need a central administration to enable them to manage all the computing device.<br /><br />However, people are invoke with technologies lot more than people live in the older days,<br />individual or family also need there own IT management ...<br /><br />1) individual who want to use all his/her computer device all in one entry<br />2) family to share all the resource<br /><br />And for sure, <span class="dct-tt">nowadays we can do things like this for enterprise/companies/education institutes<br /><br /></span><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj13SF3dcemR0o1azpMfhHEQN5lBjbeYTZ7GmJ_0SHaJIBz5dE-GwVX9JU7FTKeSeZxAqZ1xiaw9uPU5ViEnlsAJwBNwuGEeq7bDNtmWaaGjrIcWawxgGv7db3LROvJWe7aPI0LXDvyNuk_/s1600/1.png"><img style="cursor: pointer; width: 400px; height: 294px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj13SF3dcemR0o1azpMfhHEQN5lBjbeYTZ7GmJ_0SHaJIBz5dE-GwVX9JU7FTKeSeZxAqZ1xiaw9uPU5ViEnlsAJwBNwuGEeq7bDNtmWaaGjrIcWawxgGv7db3LROvJWe7aPI0LXDvyNuk_/s400/1.png" alt="" id="BLOGGER_PHOTO_ID_5454866563016060738" border="0" /></a><br /><br />Migrate all the IT manage system onto the cloud,<br />instead of hosting the management system on-premises, we host it on to cloud.<br /><br />For IT management vendor, they no longer need to maintain the server, they just focus on how to make there management software to meet customers needs.<br /><br />And because the cloud can provide "pay as you go", now the IT Management vendor can also easily offer "pay as you go" for using there service.<br /><br />Now interesting things happened.<br />The idea of office automation, home automation have been there for ages, but why still lots of the people cannot take the benefit, that is because it will be too much to buy, install and maintain the devices, software system all kind of stuff.<br /><br />But now all the price are going down,<br />for IT management vendors, they can just create a multi-tenancy architecture IT management system.<br />and i assume all digital device will be able to control via internet,<br />and the multi-tenancy architecture IT management system will allow user to plug-in Printer, Fax machine, Fridge, Air Conditioner, Washing machine etc .....<br /><br />then something like this can be happened<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1Nj1cy3GwhpBju1nEGIujyGnZeH-s-ZfdA02MrNDuy0-d89e_Dfz2MrPwWK8UIjbrjU13Q-OmCBGLHYzkq44BMlDg2XWNboR7HaahihDg1BjSIyWHpQDZ8FWTjWs-npF00oXYIyXfOIoP/s1600/2.png"><img style="cursor: pointer; width: 400px; height: 275px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1Nj1cy3GwhpBju1nEGIujyGnZeH-s-ZfdA02MrNDuy0-d89e_Dfz2MrPwWK8UIjbrjU13Q-OmCBGLHYzkq44BMlDg2XWNboR7HaahihDg1BjSIyWHpQDZ8FWTjWs-npF00oXYIyXfOIoP/s400/2.png" alt="" id="BLOGGER_PHOTO_ID_5454884765705364530" border="0" /></a><br /><br />Imaging just like nowadays mobile plan service, maybe in the future IT management vendor will also offer home device management service, let say you pay 30 bucks a month, it will allow you to have a dashboard to see how much electricity you have been consume, what are the condition of the device, and allow you to schedule or even make a work-flow to turn on and shutdown devices etc.....<br /><br /><br /><br />Bullshit ends...Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com2tag:blogger.com,1999:blog-1031083463115071586.post-11254393188821934502010-04-01T05:12:00.006+11:002010-04-01T06:49:45.661+11:00A pattern for how to do monitoring on distributed, large scattered applicationsComing soon ...<br /><br />Real project was done, will be update once some copy right issue is done ...Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com0tag:blogger.com,1999:blog-1031083463115071586.post-91754593615619944772010-02-12T09:52:00.006+11:002010-02-12T10:20:49.934+11:00WCF Service In Windows Azure Worker Role<span style="text-decoration: underline;"></span>I am going to show you how to create a WCF web service which will be hosted on a worker role in Windows Azure.<br /><br />Before we continue, i assume you already know how to create a helloworld WCF web service, also know how to deploy application onto Windows Azure and know what is input endpoint.<br /><br /><span style="font-weight: bold;">Step 1 - Create a WCF Service</span><br /><br />When creating a WCF service, always we need to define a contract and them implement it.<br /><br />There is one thing i need to raise. When implementing the contract, and if you want to use any other binding rather than BasicHttpBinding, we need to specify<br />[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]<br /><br /><blockquote><br />using System;<br />using System.Collections.Generic;<br />using System.Linq;<br />using System.Runtime.Serialization;<br />using System.ServiceModel;<br />using System.Text;<br /><br />namespace WorkerRole1<br />{<br />[ServiceContract]<br />public interface IMessageDeliver<br />{<br /> [OperationContract]<br /> void DoWork(string message);<br />}<br />}<br /></blockquote><br /><br /><blockquote><br />using System;<br />using System.Collections.Generic;<br />using System.Linq;<br />using System.Runtime.Serialization;<br />using System.ServiceModel;<br />using System.Text;<br />using System.Diagnostics;<br />using Microsoft.WindowsAzure.ServiceRuntime;<br /><br />namespace WorkerRole1<br />{<br />[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]<br />public class MessageDeliver : IMessageDeliver<br />{<br /> public void DoWork(string message)<br /> {<br /> Trace.TraceInformation("{0} Receive Message - {1}.", RoleEnvironment.CurrentRoleInstance.Role.Name, message);<br /> }<br />}<br />}<br /></blockquote><br /><br /><span style="font-weight: bold;">Step 2 - Open a port to listen </span><br /><br />In the ServiceDefinition.csdef, we need to define a InputEndpoint, so that the outside world can talk to our worker role.<br /><br />I am going to use NetTcpBinding, so i make the port as tcp. The other options you can have are http and https, which need to be match to the binding u are going to use.<br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8qpk5cQ58sMoZTvdfJFYyxkCaGCb08wkH7XxKUoF9yueVCgHxtEBG-WPUGBTQdgQAS3uPdDiGZn6tSLrBA-oP7raim49_brcTF05DdTn4PABA0GbrybY5xyVjy7Jcin9GKrNGX_QElM2A/s1600-h/Untitled.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 96px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8qpk5cQ58sMoZTvdfJFYyxkCaGCb08wkH7XxKUoF9yueVCgHxtEBG-WPUGBTQdgQAS3uPdDiGZn6tSLrBA-oP7raim49_brcTF05DdTn4PABA0GbrybY5xyVjy7Jcin9GKrNGX_QElM2A/s400/Untitled.png" alt="" id="BLOGGER_PHOTO_ID_5437129049613803762" border="0" /></a><br /><br /><br /><span style="font-weight: bold;">Step 3 - Combine WCF with the port we open</span><br /><br /><blockquote><br />ServiceHost serviceHost = new ServiceHost(typeof(MessageDeliver));<br /><br />NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);<br /><br />// define an external endpoint for client traffic<br />RoleInstanceEndpoint externalEndPoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["MessageDeliver"];<br /><br />string endpoint = String.Format("net.tcp://{0}/MessageDeliver", externalEndPoint.IPEndpoint);<br /><br />serviceHost.AddServiceEndpoint(typeof(IMessageDeliver), binding, endpoint);<br /><br />serviceHost.Open();<br /></blockquote><br /><br />Step 4 - Create a client to double check<br /><br /><br /><blockquote> ChannelFactory<imessagedeliver> cfactory = new ChannelFactory<imessagedeliver>(new NetTcpBinding(SecurityMode.None), "net.tcp://accountname.cloudapp.net:10080/MessageDeliver");<br /><br />var client = cfactory.CreateChannel();<br /><br />client.DoWork("hi from shrimpy");<br /><br /></imessagedeliver></imessagedeliver></blockquote>Done !!! Have fun ...Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com5tag:blogger.com,1999:blog-1031083463115071586.post-89564072596558728582009-12-15T14:00:00.008+11:002010-01-09T02:50:30.303+11:00Auto migrate exising ASP.NET application onto Windows Azure<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/kkUolX8-czk&hl=en&fs=1"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/kkUolX8-czk&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object><br /><br /><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/jcLUHSS0Vsg&hl=en_US&fs=1&"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/jcLUHSS0Vsg&hl=en_US&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object><br /><br /><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/1cOzH79ck6E&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/1cOzH79ck6E&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object><br /><br />Source code Package <a href="http://shrimpysprojects.googlecode.com/files/AutoDeployRobot_WithCommandFile.zip">AutoDeployRobot_WithCommandFile.zip</a><br /><br />In this video I am going to show how to migrate a existing ASP.net Application to Windows Azure.<br /><br />There will be two way, 1) via application 2) via powershell script<br /><br /><br />SOmething you need to know:<br /><br />We will use Azure Management API and Azure storage API for this demo.<br /><br />In order to pass Azure Management API authentication, we need the Subscription ID and a Self-signed X509 certificate<br /><br />In order to pass Azure storage API authentication, we need the Account Name and Access Key<br /><br />When try to do auto deploy, we have to save deployment file onto azure blob storage first, then ask Windows azure to look for the file from the storage to make the deployment.<br /><br /><br />Demo 1, migrate via an application which implentment by using Azure Management API and Azure storage API<br /><br />1) show the existing asp.net application<br /><br />2) create a service definition file<br /><br />3) use cspack to pack the application<br /><br />4) upload file onto blob storage<br /><br />5) deployment onto windows Azure<br /><br />a web role "Ganda" will call the management API to deploy the application onto Azure, after that, the web role pass a message to a worker role "Ant", the worker<br /><br />role will keep checking the satus of the deployment, once it was deployed, the worker role will ask the deployment to run<br /><br /><br />Demo 2, migrate via powershell script<br /><br />automatically do all the job from step 3 to 5 in demo 1<br /><br />Thank you for watching...Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com3tag:blogger.com,1999:blog-1031083463115071586.post-2886152806683233392009-09-28T17:30:00.012+10:002009-10-11T16:13:08.814+11:00All the bad things in Amazon Web ServiceHi folks.... This article is going to list all what i experience the shit stuff from Amazon Web Service...<br /><br />I admit that AWS is very powerful, but you have to be convinced that nothing is perfect, they will have their down side...<br /><br /><br />1) You can`t delete an instance from your list after you terminate it.<br />Your instance list will keep growing, depending on the "garbage clean up" of AWS. AWS say they will delete your termination instance at later certain period of time. But when??? Only God will know.<br /><br />2) You can`t restart a terminated instance<br />Amazon will keep billing you if you do not terminate the instance. This is painful, coz sometime we just want to do some test setup, not really launch the server for real. Let say i want to install five piece of software into my machine, today i do two, and want to do another three tomorrow. In EC2, I cannot say turn off the computer and restart it again tomorrow. I have to pay for the extra idle time.<br /><br />3) It is hard to do Authentication programatically<br />Either Query Approach or SOAP Approach, Amazon do not provide detail in-depth tutorial or document to guild us developer to do the authentication.<br />All we got is a simple page, to show us, we need to do URL Encoding when using Query API, we have to attache the X509 certificate with every request we make when usning SOAP API.<br />That is all....<br />No wonder the opensource project <a href="http://code.google.com/p/typica/">Typica </a>and <a href="http://www.blogger.com/code.google.com/p/netflexity-amazonws-ec2" style="text-decoration: none; color: rgb(255, 255, 255);">Netflexity-amazonws-ec2</a> is so popular in Amazon support forum....<br /><br />I was trying to use native Query API and SOAP API at the begining...but give up after a few hour try...i give up..coz there is no documentation..i end up reading source code from Typica and Netflexity.....so i just us Typica........so frustrated...<br /><br />But on the other hand..<a href="http://blogs.msdn.com/windowsazure/archive/2009/09/17/introducing-the-windows-azure-service-management-api.aspx">Microsoft Windows Azure management API </a>is so easy to use.<br />I learn and play straight away...<br /><br />4) Amazon-EC2-AMI-Tools Linux only<br />This tool set, there is no support for Windows.<br />Have to use third-party tools such as ElastixFox (Firefox plugin)<br /><br />5) Disk limitation when bundle Windows Instance (create custom windows AMI)<br />The basic template we can get from Amazon is a windows 2003 server with C drive only 10G.<br />And we cannot chance the size of the C drive.<br />Why i keep mention the C drive, coz all custom stuff, if you do not put into C drive, when you perform bundle, only C drive will be bundle, all other data in other drivers will be ignnore.<br />(Linux instance also has similar problem, all custom stuff have to put under /mnt, otherwise your own data won`t be bundled)<br />Coz the work i am doing is that, i need to raise multiple instance which running the same application.<br />So my solution is that, i create my own AMI, which has been config everything, when i what more, i just raise a instance from that AMI.<br />But with 10G limitation, i just cannot feel satisfaction, lucky everything i need after installing into the C driver, there still 3 to 4 G space left...but i just cannot imaging...how about my application become larger?...dose it mean i have to give up using Amazon EC2???<br />Anyway, i haven`t totally confirm that there is no way to walk around this limitation.<br />I saw one of the post in the Amazon support forum, they say we can plug-in volumn for extra space...hmm..i am thinking, whether when create a custom AMI, we can bundle the volumn as well.<br />Further investigation is needed... and i will keep update after if anything is found...<br /><br />To be continue ...Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com0tag:blogger.com,1999:blog-1031083463115071586.post-10951156130544113172009-09-21T21:30:00.006+10:002009-09-22T11:20:18.446+10:00Time to build a version control app for Azure<h2><a href="http://blogs.msdn.com/windowsazure/archive/2009/09/17/introducing-the-windows-azure-service-management-api.aspx">Introducing the Windows Azure Service Management API</a></h2><br />Azure has release its management API.<br /><br />Now azure has most of the stuff, but there is one thing Azure do not have.<br /><br />Deployment version control....<br /><br />If you want to down-grade your deployment, and if your stageing deployement is not the down grade version.<br /><br />there is no way for you to down grade.<br /><br />Since the management API has been release....it is time for version control now....<br /><br /><br /><span style="font-size:180%;"><span style="font-weight: bold;">Blueprint</span><span style="font-weight: bold;">:</span></span><br /><br />Feature:<br />1) Do not store any user information<br />2) Store data in user`s storage<br /><br />Howto Implement:<br />1) The Version Control App(VCA) is a web portal<br />3) When user come to VCA, user need to provide keys, subscritionID etc,<br />for VCA to access SQL Azure or Table Stroage, in order to store version info, to access Blob storage, in order to storage deployment files.<br />4) VCA is only a graphical interface. But behind the scene, some logic were applied to organize those data, in order to provide version control. And for sure, VCA will invoke Azure Service Management API, to help user swap deployement doing upgrade or downgrade.Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com0tag:blogger.com,1999:blog-1031083463115071586.post-24814409863307936342009-08-31T16:49:00.005+10:002009-09-02T15:32:44.656+10:00How to do stateful Registration In Windows Azure when using multi instancesMicrosoft Windows Azure cloud enable you to horizontally scale out your application by modified the number of instance on the fly, and the fabric controller will handler the load balance for you.<br /><br />But one issue is that, u cant do stateful application for this kind of scale.<br /><br />For example, user login.<br />Normally the way we do login is that. Once the user has been successfully login, we put some of the data into session, so that our application will know the user has been login within the time out duration.<br /><br /><span style="font-size:180%;"><span style="font-weight: bold;">ISSUE</span></span><br />However, when multi-instance running the same piece of application, if you store info in one of those instances, the other instance wouldn`t be aware of the user has been login.<br /><br />Below is the work around for using multi-instances.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6Fdd-6zuJZ8IxadjL40J9pmxp-ytDOCQxvz_-pb3H1tzJq2UjiX1EIM6u32JRSOswRaAWKdykYzy0Cp02x7XzZ4W3-FazfrBKcd40sMDdlBPOjsmBUjw7gYon-Ctc7OUXlrBNUOBLh1vb/s1600-h/register.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 190px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6Fdd-6zuJZ8IxadjL40J9pmxp-ytDOCQxvz_-pb3H1tzJq2UjiX1EIM6u32JRSOswRaAWKdykYzy0Cp02x7XzZ4W3-FazfrBKcd40sMDdlBPOjsmBUjw7gYon-Ctc7OUXlrBNUOBLh1vb/s400/register.png" alt="" id="BLOGGER_PHOTO_ID_5376452481902645538" border="0" /></a><br />What i am going to do is that,<br /><br />Web Roles:<br />Every time a web role receive one request, check whether there is a login record in the table storage, if the data existed (e.g we can use the userid for RowID, if the userid existed), then see the lable "expired" for every row,<br /><br />if it is false, which mean the user has already login, update the label "last_visit"<br />otherwise, hasn`t login, direct to login page.<br />after successful login, create one entry in the table.<br /><br /><br />Worker Role:<br />Schedule tasks to check the session table, see whether "current_time" - "last_visit" > time out<br />if true, set "expired" to true, otherwise set to false.<br /><br /><br /><span style="font-size:180%;"><span style="font-weight: bold;">Concerned</span></span><br />1) Data consistency<br />Data might updated by one instance, but when another instance call for the same piece of data, that data might not be updated, maybe still getting the old value.<br /><br />2) Too much over head<br /><br /><span style="font-weight: bold;font-size:180%;" >Conclusion:</span><br />I think this approach is doable.<br /><br />For consistency, even the value we read is the old value, which mean the time out wouldn`t be the exact time as we specify. Maybe it will be a bit larger or smaller then the expected value.<br /><br />For over head. There is something we need to compromise, in order to have horizontal scalability.<br /><br /><span style="font-size:180%;"><span style="font-weight: bold;"><br />How about other Cloud</span><span style="font-weight: bold;">:</span></span><br />I only want to talk about Google App Engine here, coz gogrid or amazon web service, there are more likely offer "vertical scale out".<br /><br />In Google App Engine, they already offer user the MEM-Cache, which can be shared by all the instances. And the access time or speed is fast.<br /><br />Which mean it would be easy and simple to implement my approach in Google App Engine.<br />And we won`t has the two concerns as well.Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com0tag:blogger.com,1999:blog-1031083463115071586.post-79241985620903344522009-08-22T00:15:00.005+10:002009-08-22T00:21:29.133+10:00News about cloud computing evaluation on Microsoft Windows Azure, Google App engine, Amazon Web ServicePreviously, Liang, Fei and I did a cloud evaluation project under the guidance of Professor Anna Liu.<br /><br />Now seems our report is going to be release to be a publish....<br /><br />Anna was interviewed by <a href="http://www.itnews.com.au/News/153451,stress-tests-rain-on-amazons-cloud.aspx">ITNews</a>,and talked some of the result from our project.<br /><a href="http://news.cnet.com/8301-13846_3-10314021-62.html">Cnet</a> also publish a short article about Anna`s talk.<br /><br />Hopefully by the time our report is released, we will get some good feedback.Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com0tag:blogger.com,1999:blog-1031083463115071586.post-78830683470633013732009-08-14T21:40:00.003+10:002009-09-29T01:26:24.371+10:00Poor .Net Service Bus Java SDk ...In this article i am <span style="font-weight: bold;">NOT </span>going to show you how to do things with .Net Service Bus Java SDK.<br /><br />But show you some of the facts i found out from my experiments.<br />(I used <a href="https://metro.dev.java.net/">Metro</a> to create service to connection to .Net Service Bus)<br /><br /><br /><span style="font-weight: bold;font-size:180%;" >1) Java To Java Only support SOAP 1.2</span><br /><br />I was struggling for some days, when i didn`t pay too much attention on the release notes,<br />and trying to create a demo, asking java subscriber to talk to java publisher.<br /><br />Later my friend Liang found out that, Java SDK only support SOAP 1.2 protocal.<br /><br />Coz by default, metro is using SOAP 1.1.<br />So when you program with metro, make sure u specify proper binding for your impl class<br /><br /><br />SOAP 1.2<br /><pre class="prettyprint lang-java"><span class="lit">@BindingType</span><span class="pun">(</span><span class="pln">value</span><span class="pun">=</span><span class="str">"http://java.sun.com/xml/ns/jaxws/2003/05/soap/bindings/HTTP/"</span><span class="pun">)<br /><br /><br /><span style="font-size:180%;"><span style="font-weight: bold;">2) Too much overheading</span></span><br /><br />First let`s have a look how many packages would be sent if we use .Net technology to .Net technology<br /><br /></span><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5zLuc0rz27xxXVdXMHUPi6ID2Bej91kyRwg0FtlThS_XZ7ToHeCJT6T95Xk2b6Q18OHq0XxSVnWAu0UvlAqj31q0eDy0TxbQjvhRrsCP8a1twjbhnSrGdLFSjY_9DbDUM3BLLFnojAzc0/s1600-h/1.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 191px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5zLuc0rz27xxXVdXMHUPi6ID2Bej91kyRwg0FtlThS_XZ7ToHeCJT6T95Xk2b6Q18OHq0XxSVnWAu0UvlAqj31q0eDy0TxbQjvhRrsCP8a1twjbhnSrGdLFSjY_9DbDUM3BLLFnojAzc0/s400/1.jpg" alt="" id="BLOGGER_PHOTO_ID_5376010810851490562" border="0" /></a>Start from the highlight.<br />Only four package will be sent for doing one round-trip conversation.<br /><br />Now let have a look at the java to java (Be prepared and don`t be scared).<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfDVYJTpNdRxZfvb_DirzFVcmefiLWK-gq_3u_J5PAyiuMdaZ60W-JImY2MkVQUS-Ra_xzm9-j_vkAcUtTDh1GqcyEFwUoRKxmKQOsI_KbzPc8RMtcOQM-yxEbF0lVHMRFAZyz4lc8fCsQ/s1600-h/2.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 292px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfDVYJTpNdRxZfvb_DirzFVcmefiLWK-gq_3u_J5PAyiuMdaZ60W-JImY2MkVQUS-Ra_xzm9-j_vkAcUtTDh1GqcyEFwUoRKxmKQOsI_KbzPc8RMtcOQM-yxEbF0lVHMRFAZyz4lc8fCsQ/s400/2.jpg" alt="" id="BLOGGER_PHOTO_ID_5376011833070785842" border="0" /></a>Yep..i am not joking, the whole page, starting from the top till the end of the pic,<br />it took so much to finished one round-trip conversation.<br /><br /><br /></pre>Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com1tag:blogger.com,1999:blog-1031083463115071586.post-1971778031275021042009-08-14T20:14:00.010+10:002009-08-17T17:40:47.161+10:00.Net Service Bus, another proposal between java and C# in REST approachIn this tutorial i will show you how to communicate between java techology and C# technology in REST Approach<br /><br /><span style="font-weight: bold;font-size:180%;" >Scenario:</span><br /><br />A console C# application want to provide service onto internet, so register an endpoint in the .Net Service bus, which allow people making REST request.<br /><br />After knowing there is a service in the .Net Service Bus, someone include such service into there java application with the help of HttpClient library.<br /><br /><br /><span style="font-weight: bold;font-size:180%;" >C# service</span> :<br />In this part, we are going to create a REST service provider by using WCF framework.<br /><br />1) Create a normal C# console project from Visual Stuido, choose what even name you like.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4SA4rCEa-de-e30RQPnHnoFUQqZHtvnFb4UUJ0f0y73c0Xw2N0X4cA04f8Wm5uILHw-aD-aDJLCIHG8KyjJPM7udeh4imA2zt7KJN5gp7jAfQUpIx2Nz9aIiqtHZXMRXESYxJvUT-eceR/s1600-h/1.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 268px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4SA4rCEa-de-e30RQPnHnoFUQqZHtvnFb4UUJ0f0y73c0Xw2N0X4cA04f8Wm5uILHw-aD-aDJLCIHG8KyjJPM7udeh4imA2zt7KJN5gp7jAfQUpIx2Nz9aIiqtHZXMRXESYxJvUT-eceR/s400/1.jpg" alt="" id="BLOGGER_PHOTO_ID_5370805653071588226" border="0" /></a><br />2) Within the project, create a service contract.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSeIThoShnMK3pvnQK8_Z1R46safa2gin0mjpJVAWir2wuypPBoQwvtK_xoBl3ScwgwSChhXd1oGb-zj7V9S6KMnx4ik5rXidLFs2L4Wn8YirqpGiGO9rSfCBVnGCMOwZq22BLdS7jxxHh/s1600-h/2.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 367px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSeIThoShnMK3pvnQK8_Z1R46safa2gin0mjpJVAWir2wuypPBoQwvtK_xoBl3ScwgwSChhXd1oGb-zj7V9S6KMnx4ik5rXidLFs2L4Wn8YirqpGiGO9rSfCBVnGCMOwZq22BLdS7jxxHh/s400/2.jpg" alt="" id="BLOGGER_PHOTO_ID_5370806198176196690" border="0" /></a><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9haSw6LybbLX4V3VqOJbKuHYzv-GVYox3EuDOmSIHdhtutcvTu5-6JsaJ95383ISMpm7RqIkfWWdjmYklAA1FfqcTJeiVFIA5CDxgoHixsTJcEgkqHITtoObVW6hhrtcjKa2U7OTTmLTC/s1600-h/3.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 248px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9haSw6LybbLX4V3VqOJbKuHYzv-GVYox3EuDOmSIHdhtutcvTu5-6JsaJ95383ISMpm7RqIkfWWdjmYklAA1FfqcTJeiVFIA5CDxgoHixsTJcEgkqHITtoObVW6hhrtcjKa2U7OTTmLTC/s400/3.jpg" alt="" id="BLOGGER_PHOTO_ID_5370806324764742418" border="0" /></a>3) Leave the contract blank first, coz we need to import some WCF reference.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9jrlomUwoZzU824pc6jitEmLUE2_nGQQ_Xtad7pTu77gScIOejc47ugGBL0_nYM9N4j7gyHeFb8tkHt8EAYBqYRhlC4AHIGNgY2cFZWcitpMNKK_np-bhC2LixSx8UUbjrGYLBwgZlIZ-/s1600-h/4.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 310px; height: 183px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9jrlomUwoZzU824pc6jitEmLUE2_nGQQ_Xtad7pTu77gScIOejc47ugGBL0_nYM9N4j7gyHeFb8tkHt8EAYBqYRhlC4AHIGNgY2cFZWcitpMNKK_np-bhC2LixSx8UUbjrGYLBwgZlIZ-/s400/4.jpg" alt="" id="BLOGGER_PHOTO_ID_5370806880531441602" border="0" /></a><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhg2SC2203RU-z8aluhjLy8elKoAiOIE0TKK2YNb4-CTcSEtQXxO_Lg7TtFAN6DsEREPn2OzinUoJhBILZmvwNmfsLBqut2XGemp9afPXvCQxtjGppm9xx8lJOUerqOVkTzWDCPAcdh6uGv/s1600-h/5.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 339px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhg2SC2203RU-z8aluhjLy8elKoAiOIE0TKK2YNb4-CTcSEtQXxO_Lg7TtFAN6DsEREPn2OzinUoJhBILZmvwNmfsLBqut2XGemp9afPXvCQxtjGppm9xx8lJOUerqOVkTzWDCPAcdh6uGv/s400/5.jpg" alt="" id="BLOGGER_PHOTO_ID_5370806983769483906" border="0" /></a><br />4) Now we can implement our contact with WCF annotation.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVDrpMTgboGY3VXbpCKwzYdPFgQqqPN_6r12xShA7WG_TMkbSc3XZTmRep-FyqoGB1QGfaIosaI-M46cTiJuvKOjVwreUYD8JXIuTOmZqCtFvSeZqlCNdnEbmaBqU90xHDhSpON2c7C9_z/s1600-h/6.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 256px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVDrpMTgboGY3VXbpCKwzYdPFgQqqPN_6r12xShA7WG_TMkbSc3XZTmRep-FyqoGB1QGfaIosaI-M46cTiJuvKOjVwreUYD8JXIuTOmZqCtFvSeZqlCNdnEbmaBqU90xHDhSpON2c7C9_z/s400/6.jpg" alt="" id="BLOGGER_PHOTO_ID_5370807212618925970" border="0" /></a>5) After we have the contract, it is time to do the Implementation for the contract.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLp_Mj9Nku9orcLFgNmQSLuBVtftJG477MVyBy2uLdCXih3v75m9whKN2eIgdIpZ6Wf-SV92effu5_kZHgLuQMcDTa1Wv_vE2xDwS8reFFnpx_mO101WC6JzpkmQjzJJq6_23oBs-kMjo3/s1600-h/7.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 245px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLp_Mj9Nku9orcLFgNmQSLuBVtftJG477MVyBy2uLdCXih3v75m9whKN2eIgdIpZ6Wf-SV92effu5_kZHgLuQMcDTa1Wv_vE2xDwS8reFFnpx_mO101WC6JzpkmQjzJJq6_23oBs-kMjo3/s400/7.jpg" alt="" id="BLOGGER_PHOTO_ID_5370807867462913762" border="0" /></a><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEha3T7k6qFmNwejjkmHqhIPKIznZLBU2pBd02MNPcUzEoXH4BhHxltlT5EVVbF0qCNpXOPCHcYbiqANl4eq_pe1nTQU1TUT9mLsvhz058-fzuw5HLP83K7Zn1ljjAq3GwQ_UoPz3GA3-w98/s1600-h/8.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 146px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEha3T7k6qFmNwejjkmHqhIPKIznZLBU2pBd02MNPcUzEoXH4BhHxltlT5EVVbF0qCNpXOPCHcYbiqANl4eq_pe1nTQU1TUT9mLsvhz058-fzuw5HLP83K7Zn1ljjAq3GwQ_UoPz3GA3-w98/s400/8.jpg" alt="" id="BLOGGER_PHOTO_ID_5370807921353044626" border="0" /></a><br />6) Bravo ... After all the boring jobs above, we now can create endpoint onto .Net Service Bus.<br />So here we include the Service Bus reference into our project first.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2qEZ_vR-SV2T1Q_G780a-4UqQSn6k8GjCNLsJesMR5cPYqxRsjtFpQ4LOo3JnQBZHxTNOlhzH4A2MVduE1QT03S85YgdYoMdvkUomRVYyipUwLPxtLBD6rH1LTi6J_SUg9Xa4SUtump5h/s1600-h/9.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 335px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2qEZ_vR-SV2T1Q_G780a-4UqQSn6k8GjCNLsJesMR5cPYqxRsjtFpQ4LOo3JnQBZHxTNOlhzH4A2MVduE1QT03S85YgdYoMdvkUomRVYyipUwLPxtLBD6rH1LTi6J_SUg9Xa4SUtump5h/s400/9.jpg" alt="" id="BLOGGER_PHOTO_ID_5370808577123738466" border="0" /></a><br /><br />7) Create endpoint onto .Net Service Bus.<br />This time i will do something different. If you have read my previous articles, you would find that we normally need a App.config file, however it is not a must, we can do everything in programmatical way, just the matter which way u want.<br /><pre class="brush: csharp"><br /><span style="color: rgb(51, 102, 255);">using System;</span><br /><span style="color: rgb(51, 102, 255);">using System.Collections.Generic;</span><br /><span style="color: rgb(51, 102, 255);">using System.Linq;</span><br /><span style="color: rgb(51, 102, 255);">using System.Text;</span><br /><span style="color: rgb(51, 102, 255);">using Microsoft.ServiceBus;</span><br /><span style="color: rgb(51, 102, 255);">using System.ServiceModel.Web;</span><br /><span style="color: rgb(51, 102, 255);">using System.ServiceModel.Description;</span><br /><span style="color: rgb(51, 102, 255);">using System.ServiceModel;</span><br /><span style="color: rgb(51, 102, 255);">using Microsoft.ServiceHosting.ServiceRuntime;</span><br /><br /><span style="color: rgb(51, 102, 255);">namespace ProposalService</span><br /><span style="color: rgb(51, 102, 255);">{</span><br /><span style="color: rgb(51, 102, 255);">class Program</span><br /><span style="color: rgb(51, 102, 255);">{</span><br /><span style="color: rgb(51, 102, 255);">static void Main(string[] args)</span><br /><span style="color: rgb(51, 102, 255);">{</span><br /><span style="color: rgb(51, 102, 255);">Console.WriteLine("Host starting ...");</span><br /><br /><span style="color: rgb(51, 102, 255);">//Console.Write("Your Solution Name: ");</span><br /><span style="color: rgb(51, 102, 255);">string solutionName = "shrimpy";</span><br /><br /><span style="color: rgb(51, 102, 255);">//Console.Write("Your Solution Password: ");</span><br /><span style="color: rgb(51, 102, 255);">string solutionPassword = "password";</span><br /><br /><span style="color: rgb(51, 102, 255);">// create the endpoint address in the solution's namespace</span><br /><span style="color: rgb(51, 102, 255);">Uri address = ServiceBusEnvironment.CreateServiceUri(</span><br /><span style="color: rgb(51, 102, 255);">"http",</span><br /><span style="color: rgb(51, 102, 255);">solutionName,</span><br /><span style="color: rgb(51, 102, 255);">"proposal");</span><br /><br /><span style="color: rgb(51, 102, 255);">// create the credentials object for the endpoint</span><br /><span style="color: rgb(51, 102, 255);">TransportClientEndpointBehavior userNamePasswordServiceBusCredential =</span><br /><span style="color: rgb(51, 102, 255);">new TransportClientEndpointBehavior();</span><br /><span style="color: rgb(51, 102, 255);">userNamePasswordServiceBusCredential.CredentialType =</span><br /><span style="color: rgb(51, 102, 255);">TransportClientCredentialType.UserNamePassword;</span><br /><span style="color: rgb(51, 102, 255);">userNamePasswordServiceBusCredential.Credentials.UserName.UserName =</span><br /><span style="color: rgb(51, 102, 255);">solutionName;</span><br /><span style="color: rgb(51, 102, 255);">userNamePasswordServiceBusCredential.Credentials.UserName.Password =</span><br /><span style="color: rgb(51, 102, 255);">solutionPassword;</span><br /><br /><span style="color: rgb(51, 102, 255);">WebServiceHost host = new WebServiceHost(typeof(ProposalContractImpl), address);</span><br /><br /><span style="color: rgb(51, 102, 255);">ContractDescription contractDescription =</span><br /><span style="color: rgb(51, 102, 255);">ContractDescription.GetContract(typeof(ProposalContract), typeof(ProposalContractImpl));</span><br /><span style="color: rgb(51, 102, 255);">ServiceEndpoint serviceEndPoint = new ServiceEndpoint(contractDescription);</span><br /><br /><span style="color: rgb(51, 102, 255);">serviceEndPoint.Address = new EndpointAddress(address);</span><br /><span style="color: rgb(51, 102, 255);">serviceEndPoint.Binding = new WebHttpRelayBinding();</span><br /><br /><span style="color: rgb(51, 102, 255);">serviceEndPoint.Behaviors.Add(userNamePasswordServiceBusCredential);</span><br /><br /><span style="color: rgb(51, 102, 255);">ServiceRegistrySettings settings = new ServiceRegistrySettings();</span><br /><span style="color: rgb(51, 102, 255);">settings.DiscoveryMode = DiscoveryType.Public;</span><br /><span style="color: rgb(51, 102, 255);">serviceEndPoint.Behaviors.Add(settings);</span><br /><br /><span style="color: rgb(51, 102, 255);">host.Description.Endpoints.Add(serviceEndPoint);</span><br /><span style="color: rgb(51, 102, 255);">host.Open();</span><br /><br /><span style="color: rgb(51, 102, 255);">Console.WriteLine("Service address: " + address);</span><br /><br /><span style="color: rgb(51, 102, 255);">Console.ReadLine();</span><br /><br /><span style="color: rgb(51, 102, 255);">host.Close();</span><br /><span style="color: rgb(51, 102, 255);">}</span><br /><span style="color: rgb(51, 102, 255);">}</span><br /><span style="color: rgb(51, 102, 255);">}</span><br /></pre><br /><br /><span style="font-size:180%;"><span style="font-weight: bold;">Testing our service.</span></span><br />Now the service is ready to go. Launch it, and go to your browser to test it.<br />Theoretically, you should see something like this:<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCdhwYyMtSkWuIOC30VzURCE24MNOV30b4rGwowdI4GDlzf23RLpZO2IsyJqMQcUKAMIAHLG3-lToTriSWT7J93E-Wrd1EK70ITk4H2Dsaqnkq7ERKEwmHi65QXeTDHzcsmobAl__cKyO8/s1600-h/11.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 284px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCdhwYyMtSkWuIOC30VzURCE24MNOV30b4rGwowdI4GDlzf23RLpZO2IsyJqMQcUKAMIAHLG3-lToTriSWT7J93E-Wrd1EK70ITk4H2Dsaqnkq7ERKEwmHi65QXeTDHzcsmobAl__cKyO8/s400/11.jpg" alt="" id="BLOGGER_PHOTO_ID_5370811474553136690" border="0" /></a><br />Still remember how our C# contract look like???<br />I beg u must forget all about it...<br /><br /><pre class="brush: csharp"><br /><span style="color: rgb(51, 102, 255);">[OperationContract()]</span><br /><span style="color: rgb(51, 102, 255);">[WebGet(UriTemplate = "/{words}")]</span><br /><span style="color: rgb(51, 102, 255);">string says(string words);</span><br /></pre><br />In the contract we said that, anything follow by the link will tread as input of method "says"<br />So as in the pic, if we type something following the "proposal" should trigger method "says".<br /><br />Let`s do it. See the location in my browser:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWV2eIg94wjN_JxCbQdhAVZjmq0e9Lo0GTggZrx5P964tSFhXfvcW9wLwW_YcF5wRDCqoYFQoiyQoREVBQGIMExnjjnr8xtWIDxq8BAV8TDJLw8Iwt8YpobIiyI7UMn4nhRuk9p4qADSh3/s1600-h/12.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 210px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWV2eIg94wjN_JxCbQdhAVZjmq0e9Lo0GTggZrx5P964tSFhXfvcW9wLwW_YcF5wRDCqoYFQoiyQoREVBQGIMExnjjnr8xtWIDxq8BAV8TDJLw8Iwt8YpobIiyI7UMn4nhRuk9p4qADSh3/s400/12.jpg" alt="" id="BLOGGER_PHOTO_ID_5370817136204326130" border="0" /></a><br />And then hit enter<br /><br />Oooops.......<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilEj9CP3NfHdfzk7W6ZhfsrWu0ZLrMl20jXI_QCA9BFBAE-6U-zIZCkFesM7hC6117uyXTJMtKLlLMCE_K3-n7WOFMVn1VD1B0FpjLnsdFYgjLp-DqCxCWSgWhccpjWJcVHYfpsNrnTm6R/s1600-h/13.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 200px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilEj9CP3NfHdfzk7W6ZhfsrWu0ZLrMl20jXI_QCA9BFBAE-6U-zIZCkFesM7hC6117uyXTJMtKLlLMCE_K3-n7WOFMVn1VD1B0FpjLnsdFYgjLp-DqCxCWSgWhccpjWJcVHYfpsNrnTm6R/s400/13.jpg" alt="" id="BLOGGER_PHOTO_ID_5370817405014549026" border="0" /></a>Don`t be scared, this page is from Microsoft, asking for valid login. Type in our solution name and password, it will first ask the Access Control service to do a check up, whether we have the right to get into the service on the other side. If the solution name and password are all good, it will return us a security token. For browser, the token will put into cookie, so that we can continue to visit our service.<br /><br />Bingo............ we get what we expected.......<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCTUhjxGZQwaVPnqkfjyArmtS3ZdtGNs0bh54Kkpt6o9HN8G-DjS2cEfm_gkeSBW4Y1KskwOOPQTS4DrHTPowoyOZOtLiaU4cdYfLjaqFZ90nr947hBuIXOAYjDQs8UMB8hOdCQAjizFmY/s1600-h/14.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 128px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCTUhjxGZQwaVPnqkfjyArmtS3ZdtGNs0bh54Kkpt6o9HN8G-DjS2cEfm_gkeSBW4Y1KskwOOPQTS4DrHTPowoyOZOtLiaU4cdYfLjaqFZ90nr947hBuIXOAYjDQs8UMB8hOdCQAjizFmY/s400/14.jpg" alt="" id="BLOGGER_PHOTO_ID_5370818266206769810" border="0" /></a><br /><br /><span style="font-size:180%;"><span style="font-weight: bold;">Java RESTful subscriber</span></span><br />Now we have already half way to Rome. We just need to do a rest request from the java side.<br /><br />1) Create a empty maven project. Choose any name u want.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFIH5sB0TUxVlAPleAG52Q93fNstd_KqY7aZWMD4D8BgRn_Y9SjrSjYlyDWNmrOE_uVCn-AiUi2eK6VsiUUJ1-Q31ZCZOEhiMdBP936en_d2EfUtZbfXBY_PqYBIBjSFIoPcUqrOGS5a1Z/s1600-h/20.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 297px; height: 158px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFIH5sB0TUxVlAPleAG52Q93fNstd_KqY7aZWMD4D8BgRn_Y9SjrSjYlyDWNmrOE_uVCn-AiUi2eK6VsiUUJ1-Q31ZCZOEhiMdBP936en_d2EfUtZbfXBY_PqYBIBjSFIoPcUqrOGS5a1Z/s400/20.jpg" alt="" id="BLOGGER_PHOTO_ID_5370819363061857890" border="0" /></a><br />2) Modify the POM, add HttpClient dependency, so that we can make REST request later.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdflGwmO_Uj5I1J6LPQ657hcoxZo4cTgIV05IWPq52kvOLr4i1t-wTlLEgqKByst6PBRkRnv6PWueJtSY02b88JvMXU9Gge1NrB-RLCp_KeZZN4BDAzQGjbZhQi_X04sta_2rCp68voFlR/s1600-h/16.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 266px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdflGwmO_Uj5I1J6LPQ657hcoxZo4cTgIV05IWPq52kvOLr4i1t-wTlLEgqKByst6PBRkRnv6PWueJtSY02b88JvMXU9Gge1NrB-RLCp_KeZZN4BDAzQGjbZhQi_X04sta_2rCp68voFlR/s400/16.jpg" alt="" id="BLOGGER_PHOTO_ID_5370819675184191954" border="0" /></a>3) It would be good to do logging when doing coding.<br />So create a folder "resources", and create log4j.properties file under the folder<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjybgzD7hcejUgrseqJJMt8q_xO9_nR7AEEYVyC8hp4xlpcrtUTekz0a6lFOlKBPddVeNXQQHPJK24bnZ-v4uMjvmhqEGR1S723UiE2Cxpy0biDFI1iU3sSNFImJqSLsfSKOPB2tK7hE0xY/s1600-h/17.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 195px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjybgzD7hcejUgrseqJJMt8q_xO9_nR7AEEYVyC8hp4xlpcrtUTekz0a6lFOlKBPddVeNXQQHPJK24bnZ-v4uMjvmhqEGR1S723UiE2Cxpy0biDFI1iU3sSNFImJqSLsfSKOPB2tK7hE0xY/s400/17.jpg" alt="" id="BLOGGER_PHOTO_ID_5370822834933118722" border="0" /></a><br />Content of log4j.properties:<br /><br /><pre style="color: rgb(51, 102, 255);" class="brush: java"><br />log4j.rootLogger=OFF, STDIO<br /><br />log4j.logger.org.apache.commons=ERROR<br /><br />log4j.logger.com.blogspot.cloudyshrimpy=DEBUG<br />log4j.appender.STDIO=org.apache.log4j.ConsoleAppender<br />log4j.appender.STDIO.layout=org.apache.log4j.PatternLayout<br />log4j.appender.STDIO.layout.ConversionPattern=%14p [Cloudy Shrimpy] %30.30F:%L| %x %m%n<br /></pre><br />4) So good so far, now it is time to do some real coding.<br />Let think of what should we do first.<br /><br /><span style="font-weight: bold; color: rgb(255, 0, 0);">From the white paper, it said that, in REST approach, we first need to ask for security token from Access Control Service by providing solution name and password.</span><br /><span style="font-weight: bold; color: rgb(255, 0, 0);">After we obtain the token, attache the token in http request header, then we can visit the REST service on the other side.</span><br /><br />So very straight forward i will do things like this:<br /><br /><pre class="brush: java"><br /><span style="color: rgb(51, 102, 255);">public static void main(String[] args) {</span><br /><span style="color: rgb(51, 102, 255);"> App app = new App();</span><br /><br /><span style="color: rgb(51, 102, 255);"> /**</span><br /><span style="color: rgb(51, 102, 255);"> * Get Authentication Token</span><br /><span style="color: rgb(51, 102, 255);"> */</span><br /><span style="color: rgb(51, 102, 255);"> String security_token = app.getAuthenticationToken();</span><br /><br /><span style="color: rgb(51, 102, 255);"> /**</span><br /><span style="color: rgb(51, 102, 255);"> * Send message</span><br /><span style="color: rgb(51, 102, 255);"> */</span><br /><span style="color: rgb(51, 102, 255);"> app.sendMessage(security_token, "Will you marry me");</span><br /><span style="color: rgb(51, 102, 255);">}</span><br /></pre><br /><br />Then we implement method "getAuthenticationToken" and "sendMessage"<br /><br /><pre class="brush: java"><br /><span style="color: rgb(51, 102, 255);">private void sendMessage(String token, String words) {</span><br /><span style="color: rgb(51, 102, 255);"> // replace space with '%20'</span><br /><span style="color: rgb(51, 102, 255);"> String endpoint = String.format(SERVICE_URI, words.replaceAll(" ", "%20"));</span><br /><span style="color: rgb(51, 102, 255);"> log.debug("Endpont is : " + endpoint);</span><br /><br /><span style="color: rgb(51, 102, 255);"> GetMethod get = new GetMethod(endpoint);</span><br /><span style="color: rgb(51, 102, 255);"> get.addRequestHeader(HEADER_KEY, token);</span><br /><span style="color: rgb(51, 102, 255);"> try {</span><br /><span style="color: rgb(51, 102, 255);"> int status = client.executeMethod(get);</span><br /><span style="color: rgb(51, 102, 255);"> log.debug("Request status is : " + status);</span><br /><br /><span style="color: rgb(51, 102, 255);"> if (status == HttpStatus.SC_OK || status == HttpStatus.SC_ACCEPTED) {</span><br /><span style="color: rgb(51, 102, 255);"> byte[] responseBody = get.getResponseBody();</span><br /><span style="color: rgb(51, 102, 255);"> String responseContent = new String(responseBody);</span><br /><span style="color: rgb(51, 102, 255);"> log.debug(String.format("Response is : %s", responseContent));</span><br /><span style="color: rgb(51, 102, 255);"> }</span><br /><span style="color: rgb(51, 102, 255);"> } catch (Exception ex) {</span><br /><span style="color: rgb(51, 102, 255);"> log.error("Failed to send request to service is : " + endpoint, ex);</span><br /><span style="color: rgb(51, 102, 255);"> }</span><br /><span style="color: rgb(51, 102, 255);">}</span><br /><br /><span style="color: rgb(51, 102, 255);">/**</span><br /><span style="color: rgb(51, 102, 255);"> * https://accesscontrol.windows.net/issuetoken.aspx?u=SolutionName&p=SolutionPassword</span><br /><span style="color: rgb(51, 102, 255);"> */</span><br /><span style="color: rgb(51, 102, 255);">public String getAuthenticationToken() {</span><br /><span style="color: rgb(51, 102, 255);"> String token = null;</span><br /><span style="color: rgb(51, 102, 255);"> try {</span><br /><span style="color: rgb(51, 102, 255);"> String uri = String.format(ACCESS_CONTROL_LINK_TEMPLATE, USERNAME, PASSWORD);</span><br /><span style="color: rgb(51, 102, 255);"> GetMethod get = new GetMethod(uri);</span><br /><span style="color: rgb(51, 102, 255);"> int status = client.executeMethod(get);</span><br /><span style="color: rgb(51, 102, 255);"> if (status == HttpStatus.SC_OK) {</span><br /><span style="color: rgb(51, 102, 255);"> byte[] responseBody = get.getResponseBody();</span><br /><span style="color: rgb(51, 102, 255);"> token = new String(responseBody);</span><br /><span style="color: rgb(51, 102, 255);"> log.debug(String.format("Token is : %s", token));</span><br /><span style="color: rgb(51, 102, 255);"> }</span><br /><span style="color: rgb(51, 102, 255);"> } catch (Exception ex) {</span><br /><span style="color: rgb(51, 102, 255);"> log.error("Failed to obtain authentication token.", ex);</span><br /><span style="color: rgb(51, 102, 255);"> }</span><br /><span style="color: rgb(51, 102, 255);"> return token;</span><br /><span style="color: rgb(51, 102, 255);">}</span><br /></pre><br /><br /><br />You will see lots of upper case words in my code, just because i don`t want to hardcode string. So below are all the magic strings i used.<br /><br /><pre class="brush: java"><br /><span style="color: rgb(51, 102, 255);">private static final Logger log = LoggerFactory.getLogger(App.class);</span><br /><span style="color: rgb(51, 102, 255);">/**</span><br /><span style="color: rgb(51, 102, 255);">* Solution name and password</span><br /><span style="color: rgb(51, 102, 255);">*/</span><br /><span style="color: rgb(51, 102, 255);">public static final String USERNAME = "shrimpy";</span><br /><span style="color: rgb(51, 102, 255);">public static final String PASSWORD = "password";</span><br /><span style="color: rgb(51, 102, 255);">/**</span><br /><span style="color: rgb(51, 102, 255);">* Link to get security token</span><br /><span style="color: rgb(51, 102, 255);">*/</span><br /><span style="color: rgb(51, 102, 255);">public static final String ACCESS_CONTROL_LINK_TEMPLATE = "https://accesscontrol.windows.net/issuetoken.aspx?u=%s&p=%s";</span><br /><span style="color: rgb(51, 102, 255);">/**</span><br /><span style="color: rgb(51, 102, 255);">* Target endpoint that message we are going to sent to</span><br /><span style="color: rgb(51, 102, 255);">*/</span><br /><span style="color: rgb(51, 102, 255);">public static final String SERVICE_URI = "http://shrimpy.servicebus.windows.net/proposal/%s";</span><br /><span style="color: rgb(51, 102, 255);">/**</span><br /><span style="color: rgb(51, 102, 255);">* Attribute that going to be add into the http header</span><br /><span style="color: rgb(51, 102, 255);">*/</span><br /><span style="color: rgb(51, 102, 255);">public static final String HEADER_KEY = "X-MS-Identity-Token";</span><br /><span style="color: rgb(51, 102, 255);">/**</span><br /><span style="color: rgb(51, 102, 255);">* Client that use for making REST request</span><br /><span style="color: rgb(51, 102, 255);">*/</span><br /><span style="color: rgb(51, 102, 255);">private HttpClient client = new HttpClient();</span><br /></pre><br /><br /><br /><br />Good now keep your C# service launching, and run your java application.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHxJu7MgtCnKdHUcQfJqlZj2gt1RoXfpDzVRFRfkfyD93YsvypBuJaoDZ8lQm42vhVtWmTtVbWh7_dLwNPv4soljsqXmESGni-1XiR_XLNHrhZOTCUD_FCpI3snWPvFBeQDAEYquEbumBq/s1600-h/21.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 110px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHxJu7MgtCnKdHUcQfJqlZj2gt1RoXfpDzVRFRfkfyD93YsvypBuJaoDZ8lQm42vhVtWmTtVbWh7_dLwNPv4soljsqXmESGni-1XiR_XLNHrhZOTCUD_FCpI3snWPvFBeQDAEYquEbumBq/s400/21.jpg" alt="" id="BLOGGER_PHOTO_ID_5370827750589705570" border="0" /></a><br />Do u get what i got?????Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com0tag:blogger.com,1999:blog-1031083463115071586.post-59780657994733521352009-08-08T22:30:00.022+10:002009-08-13T23:21:39.732+10:00Big Issue in .Net Service Bus When trying to communicate between JAVA and C# technology in SOAP approache<span style="font-size:100%;"><span style="font-size:100%;">Last week i was thinking to create a tutorial to show people, how different technologies can interact by using .Net Service Bus.<br /><br />However after last week`s experiment, seems that, .Net Service Bus hasn`t implement such functionality yet.<br /><br />Ok..seeing is believing.....let me show you how i found out the fact.<br /><br />My source code can be download from below.</span><br /><a href="http://shrimpysprojects.googlecode.com/files/PublisherDemoInSoapV1.rar">Publisher In C# http://shrimpysprojects.googlecode.com/files/PublisherDemoInSoapV1.rar</a><br /><br /><a href="http://shrimpysprojects.googlecode.com/files/DotNetServiceSubscriber.zip">Subscriber In Java http://shrimpysprojects.googlecode.com/files/DotNetServiceSubscriber.zip</a><br /><br /><br /><span style="font-weight: bold;font-size:180%;" >Over View:</span><br /><br />What i did for last week is that, i create a publisher service in C#, plugin into .Net Service Bus, then i create a java subscriber, and ask for service from the .Net Service Bus.<br /><br /><br /><span style="font-size:180%;"><span style="font-weight: bold;">Part one, C# Publisher Service<br /><span style="font-size:100%;"><span style="font-weight: bold;"><br />In this service, i am going to use wsHttpRelayBinding.<br /></span></span></span><span><span style="font-size:100%;"><span><br /></span></span></span></span></span>Actually i had tried most of the bindings, basicHttpRelayBinding, webHttpRelayBinding and even netTcpHttpRelayBinding.<br /><br />Q: why TcpHttpRelayBinding<br />A: 老板 also working on the same issue, try to make java communicate with C#, he try netTcp as well, i think the reason it that, when using java sdk, it only support sb as prefix.<br /><br />The result turn out to be that,<br />with netTcp and wsHttp, i got http 500 internal error,<br />with basicHttp and webHttp i got http 400 bad request error.<span style="font-size:100%;"><span style="font-size:180%;"><span><span style="font-size:100%;"><span><br /><br /></span></span></span></span></span>Later in this artile i will show u the soap package as well.<br /><br />Let start to set up the project first.<span style="font-size:100%;"><span style="font-size:180%;"><span><span style="font-size:100%;"><span><br /></span></span></span><span style="font-weight: bold;"><span style="font-size:100%;"><span style="font-weight: bold;"><br /><br /><span style="font-size:130%;">Step One: </span><br /><br /></span></span></span></span></span>Create a normal C# console application<span style="font-size:100%;"><span style="font-size:180%;"><span style="font-size:100%;"><br /><br /><br /><span style="font-size:130%;"><span style="font-weight: bold;">Step Two:<br /></span></span></span></span></span>Create interface for service contact and the impl of interface<span style="font-size:100%;"><span style="font-size:180%;"><span style="font-size:100%;"><span style="font-size:130%;"><br /><br /></span></span></span></span><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4WapXThyHNj_A1i0diWOzhGoJBpAm1vNUUPAFn5HIaUKyNDBgtw7sL6R6YkYfGQaexxRp_kRx19GpSb3HezX1JgTOaKCJGnMUZIJD8ahaWdPhn5hnU3swlA6_tIjFVTtEbrpEtt579enM/s1600-h/3.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 357px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4WapXThyHNj_A1i0diWOzhGoJBpAm1vNUUPAFn5HIaUKyNDBgtw7sL6R6YkYfGQaexxRp_kRx19GpSb3HezX1JgTOaKCJGnMUZIJD8ahaWdPhn5hnU3swlA6_tIjFVTtEbrpEtt579enM/s400/3.jpg" alt="" id="BLOGGER_PHOTO_ID_5369407634437299986" border="0" /></a><br /><span style="font-size:130%;"><span style="font-weight: bold;"><span style="font-size:130%;">Step Three, App.config</span><br /></span></span><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPSPdjKZt04CfnQAOTlqh1utT6LhD8-PC1J1I3C_k1n1-PYJCmq0toBpHmoeGM2L0kpPdsOjWY-dn2xCO9J457omPo7sjMjoIZHZysuEI6Nw_V3Fhq_pFDZyKZpyawZtuGO4oE38MvioxR/s1600-h/4.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 364px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPSPdjKZt04CfnQAOTlqh1utT6LhD8-PC1J1I3C_k1n1-PYJCmq0toBpHmoeGM2L0kpPdsOjWY-dn2xCO9J457omPo7sjMjoIZHZysuEI6Nw_V3Fhq_pFDZyKZpyawZtuGO4oE38MvioxR/s400/4.jpg" alt="" id="BLOGGER_PHOTO_ID_5369408278008746962" border="0" /></a><br /><span style="font-weight: bold;font-size:130%;" >Final Step</span>, Invoke service API, register the service onto .Net Service Bus<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSw8at3ZmUKNnoZgT2rFj0SvISRhuiMjgWBE8g17Kha1sIBuQWsDrVjG-lJPmw42FpxL9ptBDNpzP-Yskq1eyAJAftWbWbEwXwJclGlzzZg2XHyaLSXk2QbQEttjJOH7LUq8gPtP77J9rU/s1600-h/6.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 366px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSw8at3ZmUKNnoZgT2rFj0SvISRhuiMjgWBE8g17Kha1sIBuQWsDrVjG-lJPmw42FpxL9ptBDNpzP-Yskq1eyAJAftWbWbEwXwJclGlzzZg2XHyaLSXk2QbQEttjJOH7LUq8gPtP77J9rU/s400/6.jpg" alt="" id="BLOGGER_PHOTO_ID_5369410479558624178" border="0" /></a><br />In the end, the whole project will look like this:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSpFyyBo723gWE2al5noOgdMJci6uKvofIuRUlEeZqjLEwSi1MFPi3H1vRKd34481s0Kr6CuZollE_cNZ_pmWOpTSsdU7tJfrtqIHR-JsPY8PT35HFboTA3QF-1IUqVCsBqshPq3vmD7r8/s1600-h/5.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 196px; height: 131px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSpFyyBo723gWE2al5noOgdMJci6uKvofIuRUlEeZqjLEwSi1MFPi3H1vRKd34481s0Kr6CuZollE_cNZ_pmWOpTSsdU7tJfrtqIHR-JsPY8PT35HFboTA3QF-1IUqVCsBqshPq3vmD7r8/s400/5.jpg" alt="" id="BLOGGER_PHOTO_ID_5369409879564142002" border="0" /></a><br />Now right click on the project, choose<br /><br /><span style="font-size:180%;"><span style="font-weight: bold;">Debug-->Start new instance </span></span><br /><span style="font-size:100%;"><br />Theoretically you are supposed to get the app up and run<br /><br /></span><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAwxEaJMJ9iuNthUZyPY6dEHpcvjKaWuVSuK4z8nO0-xAR2VPupQkNDT2XpqdyxVmFo4_4ZzERwxQkLUl2inC7M4V6g3yFGBU507zZouYxEMVrNn5Z_a44OT8zNDX5kURXHeBup8LLalC1/s1600-h/7.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 187px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAwxEaJMJ9iuNthUZyPY6dEHpcvjKaWuVSuK4z8nO0-xAR2VPupQkNDT2XpqdyxVmFo4_4ZzERwxQkLUl2inC7M4V6g3yFGBU507zZouYxEMVrNn5Z_a44OT8zNDX5kURXHeBup8LLalC1/s400/7.jpg" alt="" id="BLOGGER_PHOTO_ID_5369412384724803090" border="0" /></a><br /><br /><br /><span style="font-weight: bold;font-size:180%;" >Part Two</span><span style="font-size:180%;"><span style="font-weight: bold;">, create WSDL file<br /><span style="font-weight: bold;"><span style="font-size:100%;"><br />Base on the C# interface, render a set of WSDL file, so that later we can use it to create java subscriber.<br /><br /></span></span></span></span><span style="font-size:100%;">I created a WCF project, base on the contact (interface) to create the WSDL, XSD files<br /><br />When testing wshttpRelayBinding and netTcpRelayBinding<br />the WCF project use wsHttpBing to generate WSDL, XSD file<br /><br />When testing basicHttpRelayBinding and webHttpRelayBinding<br />the WCF project use basicHttpBinding and webHttpBinding to generate WSDL, XSD file<br /><br /></span><span style="font-size:180%;"><span style="font-weight: bold;"><span style="font-weight: bold;"><span style="font-size:100%;">Please refer to my source code .</span></span></span></span><span style="font-size:100%;"><br /><br />The WCF project was create within the publisher project, it was a sub project.<br /></span><span style="font-size:100%;"><a href="http://shrimpysprojects.googlecode.com/files/PublisherDemoInSoapV1.rar">Publisher In C# http://shrimpysprojects.googlecode.com/files/PublisherDemoInSoapV1.rar</a></span><br /><br />if you want the WSDL file, go into <span style="font-size:100%;"><a href="http://shrimpysprojects.googlecode.com/files/DotNetServiceSubscriber.zip">DotNetServiceSubscriber.zip</a>, under src/wsdl, you will find what u want.<br /><br /></span><span style="font-size:100%;"><a href="http://shrimpysprojects.googlecode.com/files/DotNetServiceSubscriber.zip">Subscriber In Java http://shrimpysprojects.googlecode.com/files/DotNetServiceSubscriber.zip</a></span><br /><span style="font-size:100%;"><br /></span><span style="font-size:100%;"><br />PS: make sure you have fixed the endpoint and the url reference,<br /><br />e.g<br />Cox i put all the wsdl and xsd file together in one folder,<br />when getting the file from WCF, in some file, you will see<br /><br /></span><span style="font-size:100%;"><wsdl:import namespace="http://tempuri.org/" location="http://xxxxxxFileName.wsdl"></wsdl:import></span>Http://xxxxxxxxxxxxfilename.wsdl<br /><span style="font-size:100%;"><br />make sure your change it to<br /></span><span style="font-size:100%;"><br />filename.wsdl<wsdl:import namespace="http://tempuri.org/" location="FileName.wsdl"><br /><br />also, change the endpoint to<br /><br />sb://solutioname.servicebus.windows.net/endpointname<br /><br /></wsdl:import></span><span style="font-size:100%;"><span style="font-weight: bold;font-size:180%;" >Part Three, create java subscriber</span><br /><br />Base on the WSDL file, create a subscriber to connect to .net service bus.<br /><br /><span style="font-size:130%;"><span style="font-weight: bold;">Step one, create a .net service bus java project</span></span><br /><br />Please refer to my prevous article </span>to set up a java project first.<h3 class="post-title entry-title"> <a href="http://cloudyshrimpy.blogspot.com/2009/08/net-service-bus-maven-project-set-up.html">.Net service bus maven project set up with JavaSDK</a></h3><br /><span style="font-size:130%;"><span style="font-weight: bold;">Step two, add "wsimport" into POM</span></span><br /><br />wsimport can easily parse WSDL and XSD file and generate us java code<br /><br />Create a folder call "wsdl" under your src folder, and place all WSDL and XSD file into this folder.<br />Then edit your POM file as below<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_S7Wr-d5OLfe99ARWX4eLjyy70VlO4FOq2kPOAvM47kbRQhU1kXDzV_vfE1dPrdWpXxZe5ftegjO_WhUX3SA4c-Ts_D8WwO8FqMO8znUEisDvJsIYVSvqlEEzUji4kpkwKh64E3vXBwgf/s1600-h/8.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 293px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_S7Wr-d5OLfe99ARWX4eLjyy70VlO4FOq2kPOAvM47kbRQhU1kXDzV_vfE1dPrdWpXxZe5ftegjO_WhUX3SA4c-Ts_D8WwO8FqMO8znUEisDvJsIYVSvqlEEzUji4kpkwKh64E3vXBwgf/s400/8.jpg" alt="" id="BLOGGER_PHOTO_ID_5369418214996341858" border="0" /></a><br />As you see from above, if you build the project, extra java code will place into your src folder,<br />these extra java code is the contact we can use with .Net service Bus Java SDK.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMFRykNqBJF6ncuZJwJpo99iyz3SxBA-W7CPFnWrICFxHAVSZnUmBQ9Urs5xIbSHQ4TntwuEXCRbtbfjrIePnUhcPNCT8TyzsiLnw3QHTxl5I8chO5ncmo1X0Ufy2PYJ0r2gUgjrK_OUBn/s1600-h/9.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 392px; height: 206px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMFRykNqBJF6ncuZJwJpo99iyz3SxBA-W7CPFnWrICFxHAVSZnUmBQ9Urs5xIbSHQ4TntwuEXCRbtbfjrIePnUhcPNCT8TyzsiLnw3QHTxl5I8chO5ncmo1X0Ufy2PYJ0r2gUgjrK_OUBn/s400/9.jpg" alt="" id="BLOGGER_PHOTO_ID_5369418932148140690" border="0" /></a><br /><br /><span style="font-size:130%;"><span style="font-weight: bold;">Final Step , create subscriber</span></span><br /><br />Learnt from the sample of jdotnetservice.com, i create the subscriber as below<br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIWnbJzczFPdIwRZ8yqVhNqBvc4DN9_mHqd2E5KY9vLePRpXqHeKYEj6qXB_Y6TEWRcgKh7JjpKQvgbcUBqYIs2QYZTPw1F6aI700RqD1kn3vzdXN-a0SDT8NhjUIIfrskyfJJknp5It9y/s1600-h/9.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 220px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIWnbJzczFPdIwRZ8yqVhNqBvc4DN9_mHqd2E5KY9vLePRpXqHeKYEj6qXB_Y6TEWRcgKh7JjpKQvgbcUBqYIs2QYZTPw1F6aI700RqD1kn3vzdXN-a0SDT8NhjUIIfrskyfJJknp5It9y/s400/9.jpg" alt="" id="BLOGGER_PHOTO_ID_5369420088512589090" border="0" /></a><br /><br /><br /><br /><span style="font-size:180%;"><span style="font-weight: bold;">Now all the preparation have been done,<br />It is time to witness .Net Service cannot allow Cross techology communicate with SOAP approache.<br /><br />Launch your publisher service, </span> <span style="font-weight: bold;">then run the java subscriber..</span></span>..<br /><br />and you will get error information like these:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl8FG1uyFfeKKGrbmUz9z8wn2JYwPHu5SPv09HtE8EIJJf3ziBKo3W7MNbNRfWNogvNs-zJKiH2t4-XOSIxFmxM8b1olC-ljKzijUCegTLTtz9FrkfgiZCciivbWiihsq4JoefK4hOWO1m/s1600-h/10.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 179px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl8FG1uyFfeKKGrbmUz9z8wn2JYwPHu5SPv09HtE8EIJJf3ziBKo3W7MNbNRfWNogvNs-zJKiH2t4-XOSIxFmxM8b1olC-ljKzijUCegTLTtz9FrkfgiZCciivbWiihsq4JoefK4hOWO1m/s400/10.jpg" alt="" id="BLOGGER_PHOTO_ID_5369423751007071698" border="0" /></a><br />With the error info above, we don`t know what stage we had up to, so i sniffer all the package,<br />you can see from the pic below, we actually pass all the authentication, and find the service on the bus.<br /><br />However the bus failed to link the java end and C# end together.<br /><br />Q : WHY i can say that???<br />A: Because my C# code hasn`t get invoke yet...all the error happened before getting into my C# code<br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu5gNMmdhnvlICpqzin1q5TiXSldsvgKE3iS8KaNFJQr9zrrFPhXLNEOaTZfQDPEf7M2W71g50bZZjw1AavpwqZGQfpYG1hXzSocQkCUm7g-iES48BdDW62bsbvSGwou92auOB8DHysgya/s1600-h/2.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 147px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu5gNMmdhnvlICpqzin1q5TiXSldsvgKE3iS8KaNFJQr9zrrFPhXLNEOaTZfQDPEf7M2W71g50bZZjw1AavpwqZGQfpYG1hXzSocQkCUm7g-iES48BdDW62bsbvSGwou92auOB8DHysgya/s400/2.jpg" alt="" id="BLOGGER_PHOTO_ID_5369423639758521618" border="0" /></a>Also from the package sniffer, we can see the fault message<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZCcnWeXnDRZoALQqNNlPXyi0JDPCaqa5wbzYewSCpnpEj4bEmzIktThz5AnOO89Ak8qfwQsCfisk_oc2HIlFPBm5_FqzwzP8_fPrFIkvzFQ_YsFjdPZ_2ZEKNQPTMsxPR8fYywTSGEEzz/s1600-h/fault.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 101px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZCcnWeXnDRZoALQqNNlPXyi0JDPCaqa5wbzYewSCpnpEj4bEmzIktThz5AnOO89Ak8qfwQsCfisk_oc2HIlFPBm5_FqzwzP8_fPrFIkvzFQ_YsFjdPZ_2ZEKNQPTMsxPR8fYywTSGEEzz/s400/fault.jpg" alt="" id="BLOGGER_PHOTO_ID_5369427895748898994" border="0" /></a><br />Ok...let dig this problem one more step further..<br />In my C# project, i also create C# subscriber, it works perfectly. so i sniffer its package as well..<br /><br />so now we can compare what are the difference between soap package sent out from the C# subscriber and java subscriber<br /><br />SOAP package from C# subscriber:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0SHwm9C0dZhbdJXbtOM9NoIS3k3hm08jeH4e_eketQsvvgu_CNTUJ_kVaqRZQhVZuzdUD5x0hJV4jpJzIb68jRNbgMElon6KYZo-5scy3_CKxF0me6yFi609mSdsKmdoT3pNIEND7NZvU/s1600-h/11.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 307px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0SHwm9C0dZhbdJXbtOM9NoIS3k3hm08jeH4e_eketQsvvgu_CNTUJ_kVaqRZQhVZuzdUD5x0hJV4jpJzIb68jRNbgMElon6KYZo-5scy3_CKxF0me6yFi609mSdsKmdoT3pNIEND7NZvU/s400/11.jpg" alt="" id="BLOGGER_PHOTO_ID_5369426998349190450" border="0" /></a><br />SOAP package from Java subscriber when WSDL was generate from wsHttpRelayBinding:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimdoeYtO2slt3jyAQz6D36d48tPA7mIczQcQZCxothYo9M6x-WAHu1nLlTL8sb4XnQvRiqwfSWV6GfpDMbdkAJ01En3R9kAJro6WHZHJ3-u4pcFNdevis27KdaYcUESqDMiFH1coUSHnt2/s1600-h/12.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 303px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimdoeYtO2slt3jyAQz6D36d48tPA7mIczQcQZCxothYo9M6x-WAHu1nLlTL8sb4XnQvRiqwfSWV6GfpDMbdkAJ01En3R9kAJro6WHZHJ3-u4pcFNdevis27KdaYcUESqDMiFH1coUSHnt2/s400/12.jpg" alt="" id="BLOGGER_PHOTO_ID_5369428144527441874" border="0" /></a>SOAP package from Java subscriber when WSDL was generate from basicHttpRelayBinding or webHttpRelayBinding:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxvjwGNs6kQA99Q-htqA3Qt3KIqrPUkRhepxrKEwrkNP4g7jAx_EX7Y7KcFpwZ25DZjHquIwoKYiSHy0Y3bD2HTQP7tWCTNPcmqsZv7BxyiIcW4_U5R7XTGPn9pSfSMpW15pkbFcv0gR6l/s1600-h/13.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 280px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxvjwGNs6kQA99Q-htqA3Qt3KIqrPUkRhepxrKEwrkNP4g7jAx_EX7Y7KcFpwZ25DZjHquIwoKYiSHy0Y3bD2HTQP7tWCTNPcmqsZv7BxyiIcW4_U5R7XTGPn9pSfSMpW15pkbFcv0gR6l/s400/13.jpg" alt="" id="BLOGGER_PHOTO_ID_5369428806768869010" border="0" /></a><br />We can see that, the java SDK absolutely got some problem, otherwise, the chatroom will not always be there.<br /><br />But this wouldn`t be the case that affect the communication, as we can see, in C# subscriber, it did not have a "from".<br /><br />and when comparing these three file, we can see that, java subscriber use WSDL generate from basicHttp or webHttp binding , the soap package sent out would be almost the same as the C# subscriber..<br /><br />But this raise a issue...<br /><br />For what i experience, Java SDK for .Net Service Bus only support SOAP 1.2, (Another article will be come soon, taking about limitation of .Net Service Bus java sdk. which base on my prevouse prototype work, i created a java publisher and a java subscriber, and let them talk with each other)<br /><br />So when creating C# publisher, we suppose to use wsHttpRelayBinding<br /><br />However, from the SOAP package, there are big different betweent the C# subscriber and java subscriber which was using WSDL from wsHttp binding...Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com0tag:blogger.com,1999:blog-1031083463115071586.post-54778788058014339402009-08-08T01:04:00.001+10:002009-08-08T22:23:47.615+10:00.Net service bus maven project set up with JavaSDKI am a big fan of <a href="http://maven.apache.org/">maven</a>, this article will show u how to create a maven project for the .net service bus.<br /><br /><a href="http://shrimpysprojects.googlecode.com/files/DotNetServiceBusSubscriber.zip">SourceCode : http://shrimpysprojects.googlecode.com/files/DotNetServiceBusSubscriber.zip</a><br /><br />Pre-required:<br /><br />You have to go to this page:<br /><br />http://jdotnetservices.sourceforge.net/download.html<br /><br />make sure u have download everything they list, and configure you machine properly.<br /><br /><br />After you finishing everything listed in jdotnetservice, we can start now.<br /><br /><span style="font-size:180%;"><span style="font-weight: bold;"><br />Step One: Create Empty Maven Jar Project</span></span><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFYD-J7U0gOtbI63JljtDx7PmC0sDtT7G5PAurNN9g2Me_IoNVxk4E9I08jyfwiSAiDz0nJKLCoprBT_LS5PLZBpgx7SK-ZvKUS0jeGXX-mYrv32uPv2S_HTpGb78ZgmoLHsJehPp5f-gg/s1600-h/1.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 279px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFYD-J7U0gOtbI63JljtDx7PmC0sDtT7G5PAurNN9g2Me_IoNVxk4E9I08jyfwiSAiDz0nJKLCoprBT_LS5PLZBpgx7SK-ZvKUS0jeGXX-mYrv32uPv2S_HTpGb78ZgmoLHsJehPp5f-gg/s400/1.jpg" alt="" id="BLOGGER_PHOTO_ID_5367545058413456802" border="0" /></a><br />I am a Netbeans IDE user, coz it provide me friendly SVN and Maven support, but u can use what ever IDE you want, or even plain comman line to create a empty maven project.<br /><br />I did not do any fancy stuff in here, all what i did is create a empty <span style="font-weight: bold;">"Maven Quickstart Archetype"</span> project.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwxXaQC02Y0l5P5czWOhyphenhyphenkhW0f3Klubz1FktGdySBI7O7MDv7vXGqlabzD8W2FJ6L5iDJB1gScCQbWE8xOO4gaNldkgFHKmycL9UOUtViU-3b-yTXmICQQKJq7EI6zjdTlboibDWlnzciS/s1600-h/2.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 273px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwxXaQC02Y0l5P5czWOhyphenhyphenkhW0f3Klubz1FktGdySBI7O7MDv7vXGqlabzD8W2FJ6L5iDJB1gScCQbWE8xOO4gaNldkgFHKmycL9UOUtViU-3b-yTXmICQQKJq7EI6zjdTlboibDWlnzciS/s400/2.jpg" alt="" id="BLOGGER_PHOTO_ID_5367545633179031474" border="0" /></a>And i name my project "DotNetServiceBusSubscriber". The name here is trivia, just because my following tutorial is going to illustrate how to use java application to connect to a C# application via .Net Service Bus, and my C# application is a publisher (coming soon ... :P ).<br /><br /><br /><span style="font-weight: bold;font-size:180%;" >Step two: Change source version</span><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy8BpfmQzNwSEKr8kj2h1FwMWnTG-rr6Yy5tv8Hxp0V_o7rxYYOJSi0llDJxMvUhEfRbOuZP4ZhjiRfQheyjPYI-TfjV5kTdzIlATNuoZ89eT-UNpenxu1YAuxpc3KfJOLDg6KKFd6dAE4/s1600-h/3.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 394px; height: 400px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy8BpfmQzNwSEKr8kj2h1FwMWnTG-rr6Yy5tv8Hxp0V_o7rxYYOJSi0llDJxMvUhEfRbOuZP4ZhjiRfQheyjPYI-TfjV5kTdzIlATNuoZ89eT-UNpenxu1YAuxpc3KfJOLDg6KKFd6dAE4/s400/3.jpg" alt="" id="BLOGGER_PHOTO_ID_5367547032151875970" border="0" /></a>By default, maven project is using java source version 1.3, we need to change them to a newer version, 1.5 or 1.6. It is up to you.<br /><br />Right click on the project, choose Properties.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwvmdbnHOC4I7gbRHWfCW6JERfT5fcTw4Lau19nvYlHvylyF3zhunWVpvHJeHl-CVOW3MIHQtzDT4ChoqU5HGUQ4MaMtanFS3FaByuq5IC1YqSkxHzdbvjbFx-riywGKkBkIkLSqIrtbgk/s1600-h/4.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 287px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwvmdbnHOC4I7gbRHWfCW6JERfT5fcTw4Lau19nvYlHvylyF3zhunWVpvHJeHl-CVOW3MIHQtzDT4ChoqU5HGUQ4MaMtanFS3FaByuq5IC1YqSkxHzdbvjbFx-riywGKkBkIkLSqIrtbgk/s400/4.jpg" alt="" id="BLOGGER_PHOTO_ID_5367547374491193826" border="0" /></a>Select "Source" from the tree in the right hand side.<br />And change the source to 1.5 or 1.6.<br />Here i used 1.6.<br /><br />Now go to your POM file, you will see someting like this:<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJqI5PHLSiF8G8ozYdn40uLou2sBc_b0p4gjC7W6qT8oiXPSMdywKagSmmVHjMsAY_Vw661WWXE5q5nDH0u5bUkLybbaLucDJTSiQnPwwFQWNmBDzo_bqlUj4MCjw3t2q-F2Gchj1vHpf3/s1600-h/4.1.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 219px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJqI5PHLSiF8G8ozYdn40uLou2sBc_b0p4gjC7W6qT8oiXPSMdywKagSmmVHjMsAY_Vw661WWXE5q5nDH0u5bUkLybbaLucDJTSiQnPwwFQWNmBDzo_bqlUj4MCjw3t2q-F2Gchj1vHpf3/s400/4.1.jpg" alt="" id="BLOGGER_PHOTO_ID_5367548840045151090" border="0" /></a><br />PS: Hey how about i am not a NetBeans user, how can i generate this???<br /><br />In this case, you have to manually type it into your POM file.....-_-!!!!<br /><build><plugins><plugin><groupid></groupid></plugin></plugins></build><br /><br /><span style="font-size:180%;"><span style="font-weight: bold;">Step three: Dependency</span></span><br />I haven`t find any repository that provide ".Net Java SDK library" and all other jars that we need. So i decide to do all these by myself.<br /><br />Speaking in the front: make sure u have download <a href="https://sourceforge.net/projects/jdotnetservices/files/jdotnetservices/jdotnetservices-m3-ctp.zip">jdotnetservices-m3-ctp.zip</a> , and <a href="https://metro.dev.java.net/1.3/">metro</a>. It will be better that u download <a href="https://sourceforge.net/projects/jdotnetservices/files/jdotnetservices/jdotnetservices-m3-ctp_src.zip" class="externalLink">jdotnetservices-m3-ctp_src.zip </a>as well.<br /><br />Edit your POM as show in the pic<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiInpaW2UFRmVapPxV94QDAB4c5gQtUtahTIMyj29THIAgV5DSWylPDRk8b50rpM6LifNxefREeKybVXhtdFhUNu0HkgfvgBXW17kFcz-6GGnmxRqy-k9spw5WrjiE69MsL1JKT0ljMUwxx/s1600-h/5.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 273px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiInpaW2UFRmVapPxV94QDAB4c5gQtUtahTIMyj29THIAgV5DSWylPDRk8b50rpM6LifNxefREeKybVXhtdFhUNu0HkgfvgBXW17kFcz-6GGnmxRqy-k9spw5WrjiE69MsL1JKT0ljMUwxx/s400/5.jpg" alt="" id="BLOGGER_PHOTO_ID_5367550927054021954" border="0" /></a>Question: why some of the jar is specified as provided and some are 'compile'<br /><br />Answer: coz some of the jar is in my classpath, so i said they are provided, but the others, i didn`t have them in my classpath, so set to compile.<br /><br />NOW comes to the key point. All the dependency i specified here are fake, so we need to manually install all these jar.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJxbqAWtxNn_MV_idZ-ebfZmQgovuTtLCp7zuOmIPXx-A91q166nvWNMsPdy8RurPQEYjK9pVFI9wWx5s5o-mZeeiF6GWqcv8W5TdsZCz2KGRJUsF6-l0j8vAq6ImTACkmINrylxTmjGB8/s1600-h/6.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 328px; height: 233px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJxbqAWtxNn_MV_idZ-ebfZmQgovuTtLCp7zuOmIPXx-A91q166nvWNMsPdy8RurPQEYjK9pVFI9wWx5s5o-mZeeiF6GWqcv8W5TdsZCz2KGRJUsF6-l0j8vAq6ImTACkmINrylxTmjGB8/s400/6.jpg" alt="" id="BLOGGER_PHOTO_ID_5367552996813807266" border="0" /></a><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii-FcRyu4xJcpniT8hTLn5pddjS9xrW0VlicblxifL46O5CMYI1QimV0SBmKuEfOaBl7xrvr34ujT1VaOYbx5ZuvT-DXs_jETNqxndWZRctw1-fGmUTu6fB74SQDEDQXxsN5n_E08qxNs6/s1600-h/7.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 226px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii-FcRyu4xJcpniT8hTLn5pddjS9xrW0VlicblxifL46O5CMYI1QimV0SBmKuEfOaBl7xrvr34ujT1VaOYbx5ZuvT-DXs_jETNqxndWZRctw1-fGmUTu6fB74SQDEDQXxsN5n_E08qxNs6/s400/7.jpg" alt="" id="BLOGGER_PHOTO_ID_5367553116269105586" border="0" /></a><br />In the pic showed how to install jar for JDotNetService, which is Java SDK for .Net service bus,<br />another three jar is from Metro. Do the same trick for them.<br /><br />And do not forget install the source for JDotNetService. With source install, you can see the source code and java doc.<br /><br /><br />PS: Hey, how about i do not use Netbeans????<br /><span class="m"><span dir="ltr"></span></span><br /><a href="http://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html">Maven - Guide to installing 3rd party JARs</a><br /><br />This will help.<br /><br /><span style="font-size:180%;"><span style="font-weight: bold;">Final step: Do your coding</span></span><br /><br />Now is time to create your own application ....have fun...<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJ09nY7ZIM41X9pA-vFLUOAdE_UYxCfFuwonNOa1pmYFdaSM8NNxL0VMRO40VLfvgluDi3aJT1jAeCjBZwi-zTmJSKTBsOCy8TgzF8CNE7CyfqHjA66noPCGEwSl4FF60RV3yWG_L74tUc/s1600-h/8.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 211px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJ09nY7ZIM41X9pA-vFLUOAdE_UYxCfFuwonNOa1pmYFdaSM8NNxL0VMRO40VLfvgluDi3aJT1jAeCjBZwi-zTmJSKTBsOCy8TgzF8CNE7CyfqHjA66noPCGEwSl4FF60RV3yWG_L74tUc/s400/8.jpg" alt="" id="BLOGGER_PHOTO_ID_5367555052195956962" border="0" /></a>Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com2tag:blogger.com,1999:blog-1031083463115071586.post-8945916514146639082009-08-03T15:55:00.000+10:002009-08-08T01:07:00.672+10:00Peeking in .Net Service Bus "Router "The pass two day, i played with the "Router" a little bit, and try to find out what the router can do for us.<br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8D12UuwFwlr529aF_WHAvzXtg-5CloVK0dE8fGgNzHgAWHQLTum_Y7LIxOUgVs_ZhX4PDRkfrufTDsFWjMYZfpb5qG3tuBfIU1lyIUVB3JOV-pEcNJ93btY6FLPLkdMrFDdnHF6-I2q7-/s1600-h/router.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 186px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8D12UuwFwlr529aF_WHAvzXtg-5CloVK0dE8fGgNzHgAWHQLTum_Y7LIxOUgVs_ZhX4PDRkfrufTDsFWjMYZfpb5qG3tuBfIU1lyIUVB3JOV-pEcNJ93btY6FLPLkdMrFDdnHF6-I2q7-/s320/router.jpg" alt="" id="BLOGGER_PHOTO_ID_5365614043015086626" border="0" /></a><br />The pic above was quoted from the .net service bus white paper. As we can see that, Router can distribute message to a queue, a receiver or another router.<br /><br />Ok, time for criticism:<br /><br /><span style="font-size:180%;"><span style="font-weight: bold;">Cons:</span></span><br /><br />(a) Messages are directed in OneWay only.<br />Which means the relationship can only be One Sender --> Multi Receiver,<br />receiver can not interact with the sender.<br /><br />(b) the queue need to be specify by the receiver.<br />I am a bit confusing in here as well.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjP4bw8SL1DC3j1xQbE8Rk9uSN5gP4rrFtGDOYf8z71h8RxBQ__26eNW6xFHMqkb9TCLmM8nupfAdc0DFqfjmtwQpIbdKfZtH_gTkJq11n4irTyrxcpGqJktFg6LJ553bBINEVMHkibHoUt/s1600-h/router2.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 147px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjP4bw8SL1DC3j1xQbE8Rk9uSN5gP4rrFtGDOYf8z71h8RxBQ__26eNW6xFHMqkb9TCLmM8nupfAdc0DFqfjmtwQpIbdKfZtH_gTkJq11n4irTyrxcpGqJktFg6LJ553bBINEVMHkibHoUt/s320/router2.jpg" alt="" id="BLOGGER_PHOTO_ID_5365616024084352546" border="0" /></a><br /><1> I cannot see big differents or important differents between the two receiver showed in the above pic.<br />I use the sample code which came alone with the .net service sdk (publisher subscriber).<br />I made the publisher keep sending message. When Service B and A both launched.<br />Messages displayed by Service B always random.<br />for example, the sender keep sending number in acceding order e.g 1 2 3 4 5 6 7 8 9 ,<br />bur what B received would be 4 6 1 8 9 2 3 5, and B keep doing like this.<br /><br />The same thing happened on Service A as well, at the beginning, there is no order...<br />but after a little while, we can see the message displayed by Service A would become the same order as what the sender did.<br /><br />but it doesn`t make sense to me, why at the beginning, Service A display stuff is out of order???<br /><br /><2> What more, the queue in the pic, didn`t act as what i expected.<br />I was thinking, even though service A might down for a while, when the next time it come up again, it wouldn`t miss any message, coz the message will store in the queue.<br />However, the result turn out is that, if Service A is down, the next time u come up, u can only receive the latest message, if something were sent in down time of service A, service A will just miss them.<br /><br />(c) We can only play with the Router in .Net Technology.<br />Up till now, i have looked into both Java SDK in Jdotnetservice.com and Ruby SDK dotnetservicesruby.com<br /><br />Seems neither of them support router.<br />And i tried to look into the REST approach of how the .Net technology can do the router thing,<br />seems it is not enough information for us to do everything on our own.<br /><br />Maybe Microsoft should release a set of document, to show us how to connect to all its API.<br />To be honest, the java sdk is so shit, and too many over head request.<br /><br /><span style="font-weight: bold;font-size:180%;" >Pros:</span><br />(a) Sender can be down and up.<br />No matter what, a sender need to create a router into the service bus first.<br />After this, receiver can subscribe to the router.<br />And then sender would be allow down, up what ever time it wants, as long as it come back before the time out dration, which is 1 hours by default, and can be manually specify by the sender when creating the router.<br /><br />(b) Receiver can ask the sender attache a secret key with all the message which is going to send to this receiver.<br />When the receiver subscribe to the router, the receiver can push a key to the router, ask the router attache that key with all message which will be send to this receiver.<br /><br />(c) Load balance<br />Router can be configured to send message to "All" or send message to "One".<br />The usage of this kind of setting is that.<br /><br />To "ALL" which means all the subscriber will receive the message.<br /><br />To "One", if all the subscriber are the same set of service, either one of the service get the message from the router will do the job. In this case, the router will do the load balance job for you. The router will pick the most "Free" one, and send the message to that subscriber.Cloudy Shrimpyhttp://www.blogger.com/profile/07182787427012065946noreply@blogger.com0