Share What We Say



Filter by:

Blogs

Developing BizTalk Server 2010 solution for integrating with PeopleSoft Enterprise System.

BizTalkUnleashed Blog - Tue, 2012-02-21 20:36

In this post we will see few of the initial steps for developing BizTalk Solutions for integrating with PeopleSoft Enterprise Systems using PeopleSoft Adapter. In order to proceed further, you must have Installed and Configured PeopleSoft Adapter properly, both on BizTalk side and PeopleSoft System side. This particular post is based on PeopleSoft HRMS 9.0 system. But the steps shown below should be same for any PeopleSoft Enterprise System.

The steps will be same to connect to any Component Interface of PeopleSoft System. Here we will be connecting to the Employee Personal Data component interface.

Environment:

BizTalk Server 2010

Visual Studio 2010

SQL Server 2008 with SP2

PeopleSoft HRMS 9.0 with PeopleTools 8.52

Steps:

  • Open Visual Studio 2010 and create a new BizTalk Solution. In this case we named it as PSDemo.

1

  • Open BizTalk Server Administration Console and you can use any Application or you can create a new Application. Here we are using the BizTalk.EnterpriseApplication.

2

  • Go to Send Ports for this application and right click and create a new Static Solicit Response Send Port.

13

  • Name the send port appropriately and select PeopleSoft as the Transport Type and XML Transmit and XML Receive as the pipelines as shown in the screenshot.

3

  • Click Configure for the PeopleSoft Adapter and fill in the appropriate values for the PeopleSoft adapter properties. You can keep other values as default ones apart from the Application Server Path, Java_Home, Password, PeopleSoftJarFile and Username.

4

  • Click Apply –> Ok. Restart the BizTalk Host Instance and then Stat this particular Send Port. Check the event log if you have any errors after starting the Send Port.

5

  • Go back the the Visual Studio solution. Right click the project and click Add Generated Items.

6

  • Click Add Adapter Metadata.

7

  • From the list of registered adapters, select PeopleSoft Adapter and wait for a second and you will see the list of Send Ports registered with PeopleSoft Adapter. Select the one which we created above and click Next.

8

  • Wait for few seconds and you will see all the Component Interfaces for the PeopleSoft System. If you don’t see any CI then there might be some issue in your PeopleSoft Adapter configuration on the send port side. Check the Event Log for any error. For any JVM related errors, check out this blog post to fix them. It also discusses other error fixes.

9

  • Select the component interface from the list for which you want to generate the metadata for. Here we will be using CI_Personal_Data which is a component interface for PeopleSoft HRMS Employee Personal Data.

10

  • Once selected click Finish and after few seconds you will see the schemas and orchestration added for this CI.

 11     12

 

Categories: Blogs

Request a token from ADFS using WS-Trust from iOS, Objective-C, IPhone, IPad, Android, Java, Node.js or any platform or language

Leandro Boffi - Tue, 2012-02-21 05:56

This is not just a SEO friendly name, in this post I want to show you a very easy way of providing Active Directory authentication in your apps, no matter the platform or language that you use, the only requirement is to be able to make an http post.

Request for a Security Token

To talk with ADFS we must be able to speak WS-Trust protocol, on the .NET platform this is a very easy thing to do thanks to WCF and Windows Identity Foundation frameworks, but regardless the platform make a WS-Trust call is not so hard.

The first thing that we need to know is that WS-Trust protocol defines an standard way of requesting security tokens, based on an XML structure known as Request Security Token or RST, this is an example of that structure:

<trust:RequestSecurityToken xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512"> <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> <a:EndpointReference> <a:Address>https://yourcompany.com</a:Address> </a:EndpointReference> </wsp:AppliesTo> <trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</trust:KeyType> <trust:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</trust:RequestType> <trust:TokenType>urn:oasis:names:tc:SAML:2.0:assertion</trust:TokenType> </trust:RequestSecurityToken>

Focusing on the basics, there is a couple of fields that are important to us, inside of the RequestSecurityToken element you will find the AppliesTo tag where, using the WS-Addressing standard, we define the scope to which the token is valid, in this case: https://yourcompany.com.

RequestType specifies the action that you want to execute, in our case “Issue”, this means that we want that the (Security Token Service) STS issue a new token, but another option could be renewed an already issued token, in that case the RequestType would be “Renew”.

Finally, the TokenType specifies the type of the token that you want, in our case we are asking for a token based on the SAML 2.0 format.

Doesn’t looks very hard, isn’t? but where do we say who we are? well, one detail that adds a bit of complexity is the fact that all the WS-* protocols stack is build on top of SOAP, so we need to speak SOAP in order to send the token request. Once more, speak SOAP is not so hard, SOAP is also XML-Based, I’m not going to explain the whole SOAP protocol, but you can find the format for a soap message here: http://www.w3.org/2003/05/soap-envelope/

In our case, to talk with ADFS from a native client we going to use username and password security, so this is how the SOAP message will looks like: (I’ve cut some arguments to improve the presentation)

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="..."> <s:Header> <a:Action s:mustUnderstand="1"> http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue </a:Action> <a:To s:mustUnderstand="1">https://yourcompany.com/adfs/services/trust/13/UsernameMixed</a:To> <o:Security s:mustUnderstand="1" mlns:o="..."> <o:UsernameToken u:Id="uuid-6a13a244-dac6-42c1-84c5-cbb345b0c4c4-1"> <o:Username>Leandro Boffi</o:Username> <o:Password Type="...">P@ssw0rd!</o:Password> </o:UsernameToken> </o:Security> </s:Header> <s:Body> <trust:RequestSecurityToken xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512"> <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> <a:EndpointReference> <a:Address>https://yourcompany.com</a:Address> </a:EndpointReference> </wsp:AppliesTo> <trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</trust:KeyType> <trust:RequestType> http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue </trust:Requesthttps://yourcompany.com/adfs/services/trust/13/UsernameMixedType> <trust:TokenType>urn:oasis:names:tc:SAML:2.0:assertion</trust:TokenType> </trust:RequestSecurityToken> </s:Body> </s:Envelope>

To quickly understand the format, the SOAP envelop has two main tags: header and body. The body of our message contains the RST (Request for Security Token) message that we created before. In the header we can find context parameters like, the Uri of the service endpoint (To), the name of the action exposed in that endpoint that you want to execute (Action), remember that in SOAP you can have multiple actions in a single endpoint, and who we are (Security), in this case username and password.

To use UserName and Password authentication we need to look for the action Issue in the endpoint https://yourcompany.com/adfs/services/trust/13/UsernameMixed, so make sure that this endpoint is enabled on ADFS configuration.

Once we have the SOAP message, we just need to send it to the server using a regular HTTP POST, this is an example of how to do it on .NET, but it can be applied to any platform or language:

var client = new WebClient(); client.Headers.Add("Content-Type", "application/soap+xml; charset=utf-8"); var result = client.UploadString( address: "https://yourcompany.com/adfs/services/trust/13/UsernameMixed", method: "POST", data: soapMessage);

Make sure that you specify the Content-Type header to “application/soap+xml; charset=utf-8”, what you finally need to send to the server is this:

POST /adfs/services/trust/13/UsernameMixed HTTP/1.1

Connection: Keep-Alive

Content-Length: 1862

Content-Type: application/soap+xml; charset=utf-8

Accept-Encoding: gzip, deflate

Expect: 100-continue

Host: localhost

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">….</s:Envelope>

I’ve added other headers to be consistent with the HTTP Protocol, but for ADFS just the Content-Type is required.

The Answer: Request Security Token Response

If your credentials were valid, and the scope Uri is the right one, you will get a SOAP response from ADFS. In the body of that message you will get something like this:

<trust:RequestSecurityTokenResponseCollection xmlns:trust="..."> <trust:RequestSecurityTokenResponse> <trust:Lifetime>...</trust:Lifetime> <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">...</wsp:AppliesTo> <trust:RequestedSecurityToken> <Assertion ID="_fcf06a39-c495-4074-8f22-4a7df6e26513" IssueInstant="2012-02-21T04:27:24.771Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"> <Issuer>http://yourcompany.com/adfs/services/trust</Issuer> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/> <ds:Reference URI="#_fcf06a39-c495-4074-8f22-4a7df6e26513"> <ds:Transforms> <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> <ds:DigestValue>...</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>...</ds:SignatureValue> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <ds:X509Data> <ds:X509Certificate>...</ds:X509Certificate> </ds:X509Data> </KeyInfo> </ds:Signature> <Subject> <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <SubjectConfirmationData NotOnOrAfter="2012-02-21T04:32:24.771Z"/> </SubjectConfirmation> </Subject> <Conditions NotBefore="2012-02-21T04:27:24.756Z" NotOnOrAfter="2012-02-21T05:27:24.756Z"> <AudienceRestriction> <Audience>https://yourcompany.com/</Audience> </AudienceRestriction> </Conditions> <AttributeStatement> <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"> <AttributeValue>Leandro Boffi</AttributeValue> </Attribute> <Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/role"> <AttributeValue>Administrator</AttributeValue> <AttributeValue>Mobile User</AttributeValue> </Attribute> </AttributeStatement> <AuthnStatement AuthnInstant="2012-02-21T04:27:24.724Z"> <AuthnContext> <AuthnContextClassRef> urn:oasis:names:tc:SAML:2.0:ac:classes:Password </AuthnContextClassRef> </AuthnContext> </AuthnStatement> </Assertion> </trust:RequestedSecurityToken> <trust:RequestedAttachedReference>...</trust:RequestedAttachedReference> <trust:RequestedUnattachedReference>...</trust:RequestedUnattachedReference> <trust:TokenType>urn:oasis:names:tc:SAML:2.0:assertion</trust:TokenType> <trust:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</trust:RequestType> <trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</trust:KeyType> </trust:RequestSecurityTokenResponse> </trust:RequestSecurityTokenResponseCollection>

This format is also specified in the WS-Trust protocol as “Request Security Token Response” or RSTR, but for you the most important section of the response is in:

RequestSecurityToeknResponseCollection/RequestSecurityToeknResponse/RequestedSecurityToken

The content of that tag is the security token, in our case a SAML 2.0 token:

<Assertion ID="_fcf06a39-c495-4074-8f22-4a7df6e26513" IssueInstant="2012-02-21T04:27:24.771Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"> <Issuer>http://yourcompany.com/adfs/services/trust</Issuer> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/> <ds:Reference URI="#_fcf06a39-c495-4074-8f22-4a7df6e26513"> <ds:Transforms> <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> <ds:DigestValue>...</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>...</ds:SignatureValue> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <ds:X509Data> <ds:X509Certificate>...</ds:X509Certificate> </ds:X509Data> </KeyInfo> </ds:Signature> <Subject> <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <SubjectConfirmationData NotOnOrAfter="2012-02-21T04:32:24.771Z"/> </SubjectConfirmation> </Subject> <Conditions NotBefore="2012-02-21T04:27:24.756Z" NotOnOrAfter="2012-02-21T05:27:24.756Z"> <AudienceRestriction> <Audience>https://yourcompany.com/</Audience> </AudienceRestriction> </Conditions> <AttributeStatement> <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"> <AttributeValue>Leandro Boffi</AttributeValue> </Attribute> <Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/role"> <AttributeValue>Administrator</AttributeValue> <AttributeValue>Mobile User</AttributeValue> </Attribute> </AttributeStatement> <AuthnStatement AuthnInstant="2012-02-21T04:27:24.724Z"> <AuthnContext> <AuthnContextClassRef> urn:oasis:names:tc:SAML:2.0:ac:classes:Password </AuthnContextClassRef> </AuthnContext> </AuthnStatement> </Assertion>

Once we extract the token from the response, everything gets simpler: Inside of the AttributeStatment section you will have a list of Attribute, this are the claims, information of the user, for example in this token we have three different claims:

  • Type: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
  • Value: Leandro Boffi
  • Type: http://schemas.microsoft.com/ws/2008/06/identity/claims/role
  • Value: Administrator
  • Type: http://schemas.microsoft.com/ws/2008/06/identity/claims/role
  • Value: Mobile User

You can use those claims to perform authorization in your application, but also if your app needs to call webservices that rely on your ADFS, you will need to send the entire token in each request that you made to those services (I’ll explain this scenario in a future post).

Security Features

The token has some security features with which we can get us to make our application more secure. I’m not going to explain all the features in this post, but for example, if we want we can verify that no body has modified the token, because it is signed by the issuer (in our case, ADFS). You can find the signature on Assertion/Signature/SignatureValue. This signature is also based on a standard called XML Signature, you can find the specification here: http://www.w3.org/Signature/.

Also another very important feature is the fact that the token has a limited life time, to avoid that somebody use an old token, you can find that in the Assertion/Conditions/NotBefore and NotOnOrAfter.

Conclusion

Integrate the identity of our apps to Active Directory, no matter the platform or the language is possible due to ADFS is based on WS-Trust an standard protocol. If your language do not support WS-Trust natively it requires a bit more of effort, but as we saw in this post it’s not hard at all, you just need an XML template for the SOAP+RST call and an HTTP Post.

Download here the template for doing the SOAP-RST call, just replace the values in brackets with your values and start requesting tokens!

Hope has been useful!

Categories: Blogs

Integrating Backbone.js with ASP.NET Web API

Pablo Blog - Fri, 2012-02-17 20:07

In case you did not see the latest news, what we used to know as WCF Web API was recently rebranded and included in ASP.NET MVC 4 as ASP.NET Web API. While both frameworks are similar in essence with focus on HTTP, the latter was primarily designed for building HTTP services that don’t typically require an user intervention. For example, some AJAX endpoints or a Web API for a mobile application. While you could use ASP.NET MVC for implementing those kind of services, that would require some extra work for implementing things right like content-negotiation, documentation, versioning, etc. What really matter is that both framework share many of the extensibility points like model binders, filters or routing to name a few.

If you don’t know what Backbone.js is, this quote from the main page in the framework website will give you some idea,

“Backbone.js gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface. “

You see, the framework will help you to organize your javascript code for the client side using an MVC pattern, and it will also provide an infrastructure for connecting your models with an existing Web API. (I wouldn’t use the term RESTful here as it usually implies your services adhere to all the tenets discussed in the Roy Fielding’s dissertation about REST). 

That means you should be able to connect the backbone.js models with your MVC Web API in a more natural way. As part of this post, I will use the “Todos” example included as part of the backbone.js code, but I will connect that to a Web API built using the new ASP.NET Web API framework. 

On the client side, a model is defined for representing a Todo item.

// Our basic **Todo** model has `id`, `text`, `order`, and `done` attributes. window.Todo = Backbone.Model.extend({   idAttribute: 'Id',   // The rest of model definition goes here });

There is also a collection for representing the Todo list,

// The collection of todos is backed by *localStorage* instead of a remote // server. window.TodoList = Backbone.Collection.extend({   // Reference to this collection's model. model: Todo,   url: function () { return 'api/todos'; },   // The rest of the collection definition goes here });

I modified the code for this collection to override the “url” setting. This new url will point to the route of our Web API controller. Backbone will try to synchronize all the changes in the models by sending http requests with the corresponding verb (GET, POST, PUT or DELETE) to that url.

Now, the interesting part is how we can define the Web API controller using the new ASP.NET Web Api framework.

public class TodosController : ApiController { public IEnumerable<TodoItem> Get() { return TodoRepository.Items; }   public IdModel Post(TodoItem item) { item.Id = Guid.NewGuid().ToString(); TodoRepository.Items.Add(item);   return new IdModel{ Id = item.Id }; }   public HttpResponseMessage Put(string id, TodoItem item) { var existingItem = TodoRepository.Items.FirstOrDefault(i => i.Id == id); if (existingItem == null) { return new HttpResponseMessage(HttpStatusCode.NotFound); }   existingItem.Text = item.Text; existingItem.Done = item.Done;   return new HttpResponseMessage(HttpStatusCode.OK); }   public void Delete(string id) { TodoRepository.Items.RemoveAll(i => i.Id == id); } }

As you can see, the code for implementing the controller is very clean and neat. A name convention based on the Http Verbs can be used to route the requests to the right controller method. Therefore, I have different methods for retrieving the list of items (GET), creating a new item (POST), updating an existing item (PUT) or just delete it (DELETE)

A few things to comment about the code above,

  1. I haven’t specified the wire format anywhere in the code. The framework will be smart enough to do content negotiation based on the headers sent by the client side (In this case text/json).
  2. You can return any serializable class or a HttpResponseMessage if you want to have better control over the returned message (set the status code for example).
  3. The framework will take care of serialize or deserialize the message on the wire to the right model (TodoItem in this case)
  4. A hardcoded repository is being used, which is not a good practice at all, but you can easily inject any dependency into the controllers as you would do with the traditional ASP.NET MVC controllers.

Here is the class definition for the TodoItem model,

public class TodoItem : IdModel { public int Order { get; set; } public string Text { get; set; } public bool Done { get; set; } }

The IdModel is just a workaround for returning only an Id property to the client side when a new item is created. This is what backbone needs to associate an id to a new model. A more elegant solution would be to return an anonymous object with the id (such as new { Id = “xxx” }), but the default serializer for Json in the current bits (DataContractJsonSerializer) can not serialize them. Extending the built-in formatter to use a different serializer is something I am going to show in a different post.

public class IdModel { public string Id { get; set; } }

The default routing rule in the global.asax file is configured like this,

routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } );

All the calls to a API controller must be prefixed with “api”. That’s why I set the url to “api/todos” in the backbone model.

Categories: Blogs

What is Enterprise Mobility Platform As A Service And Why It Will Win

Professional ASP.NET Blog - Fri, 2012-02-17 13:46
This year enterprises are at a very pivotal crossroads when it comes to how their Line of Business (LOB) applications are architected, developed, deployed and managed. Why are they at this crossroads? Why can't they just keep plodding along the same way...(read more)
Categories: Blogs

Error while connecting with BizTalk Server Enterprise Adapter. (PeopleSoft/Siebel/JDE etc)

BizTalkUnleashed Blog - Tue, 2012-02-14 20:09

Commonly when you try to connect the Enterprise Applciatons with BizTalk Adapters you might get errors like :

E-PSFT0029: JVM was not started

OR

Unable to find JAVA_HOME.

As the error says, it is unable to locate the JVM.dll and unable to start it.

Resolution:

  • Make sure the folder having JVM is present as a value in PATH variable of environment variables. Say for PeopleSoft Applications, the JVM can be found with the app called JRockit so make sure the folder path of JRockit containing the JVM is properly present in the environment variable value.

Path Env Variable

  • Apart from PATH variable, make sure you also have a variable named CLASSPATH with the Jar file location in it. The mentioned below is a psjoa.jar file needed for PeopleSoft Adapter. 

ClassPath Env Variable

  • Download this exe and provide the path of the JVM.dll and check if its able to start it successfully. If yes then you can use this Folder path in the BizTalk Server Adapter configurations on the BizTalk Receive or Send Ports. If the JVM is unable to start with this tester then you know the problem is with this JVM.dll. May be some kind of security settings or access issues. Get the JVM.dll working.

Success:

JVMTest1

Failure:

JVMTest2

  • Make sure you have all the necessary access to the user which will be connecting to the Enterprise Application. Also for the user on which the BizTalk Host Instance, BizTalk Adapters, BizTalk Send Handlers, BizTalk Receive Handlers etc are running. For eg, for PeopleSoft Applications, you will have to configure the PeopleSoft System as shown in this post so that BizTalk Adapter can connect to it.
  • Lastly, make sure you have all the values in the BizTalk Send/Receive Port Adapter configurations properly with all the usernames, passwords, case sensitive values correctly.

Hope these helps.

Thanks,

Vishal Mody

Categories: Blogs

New Kinect for Windows Webinar

Jesus Blog - Mon, 2012-02-13 15:34
We have more Kinect for you next week. After the great feedback received with our previous webinar and to celebrate the exciting release of Kinect for Windows, Tellago will be hosting our second Kinect Technology Update next Tuesday . We will cover the...(read more)
Categories: Blogs

Hacking the browser cache with JQuery and ASP.NET MVC

Pablo Blog - Fri, 2012-02-10 15:20

Although JQuery provides a very good support for caching responses from AJAX calls in the browser, it is always good to know how you can use http as protocol for making an effective use of it.

The first thing you need to do on the server side is to supports HTTP GETs, and identify your resources with different URLs for retrieving the data (The resource in this case could be just a MVC action). If you use the same URL for retrieving different resource representations, you are doing it wrong. An HTTP POST will not work either as the response can not cached. Many devs typically use HTTP POSTs for two reason, they want to make explicit the data can not be cached or they use it as workaround for avoiding JSON hijacking attacks, which can be avoided anyways in HTTP GETs by returning a JSON array.

The ajax method in the JQuery global object provides a few options for supporting caching and conditional gets,

$.ajax({ ifModified: [true|false], cache: [true|false], });

The “ifModified” flag specifies whether we want to support conditional gets in the ajax calls. JQuery will automatically handle everything for us by picking the last received “Last-Modified” header from the server, and sending that as “If-Modified-Since” in all the subsequent requests. This requires that our MVC controller implements conditional gets. A conditional get in the context of http caching is used to revalidate an expired entry in the cache. If JQuery determines an entry is expired, it will be first try to revalidate that entry using a conditional get against the server. If the response returns an status code 304 (Not modified), JQuery will reuse the entry in the cache. In that way, we can save some of the bandwidth required to download the complete payload associated to that entry from the server.

The “cache” option basically overrides all the caching settings sent by the server as http headers. By setting this flag to false, JQuery will add an auto generated timestamp in the end of the URL to make it different from any previous used URL, so the browser will not know how to cache the responses.

Let’s analyze a couple scenarios.

The server sets a No-Cache header on the response

The server is the king. If the server explicitly states the response can not be cached, JQuery will honor that. The “cache” option on the ajax call will be completely ignored.

$('#nocache').click(function () { $.ajax({ url: '/Home/NoCache', ifModified: false, cache: true, success: function (data, status, xhr) { $('#content').html(data.count); } }); }); public ActionResult NoCache() { Response.Cache.SetCacheability(HttpCacheability.NoCache); return Json(new { count = Count++ }, JsonRequestBehavior.AllowGet); }

The server sets an Expiration header on the response

Again, the server is always is the one in condition for setting an expiration time for the data it returns. The entry will cached on the client side using that expiration setting.

$('#expires').click(function () { $.ajax({ url: '/Home/Expires', ifModified: false, cache: true, success: function (data, status, xhr) { $('#content').html(data.count); } }); }); public ActionResult Expires() { Response.Cache.SetExpires(DateTime.Now.AddSeconds(5)); return Json(new { count = Count++ }, JsonRequestBehavior.AllowGet); }

The client never caches the data

The client side specifically states the data must be always fresh and the cache not be used. This means the “cache” option is set to false. No matter what the server specifies, JQuery will always generate an unique URL so that will be impossible to cache.

$('#expires_nocache').click(function () { $.ajax({ url: '/Home/Expires', ifModified: false, cache: false, success: function (data, status, xhr) { $('#content').html(data.count); } }); }); public ActionResult Expires() { Response.Cache.SetExpires(DateTime.Now.AddSeconds(5)); return Json(new { count = Count++ }, JsonRequestBehavior.AllowGet); }

The client and server use conditional gets for validating the cached data.

The client puts a new entry in the cache, which will be validated after its expiration.  The server side must implement a conditional GET using either ETags or the last modified header.

$('#expires_conditional').click(function () { $.ajax({ url: '/Home/ExpiresWithConditional', ifModified: true, cache: true, success: function (data, status, xhr) { $('#content').html(data.count); } }); }); public ActionResult ExpiresWithConditional() { if (Request.Headers["If-Modified-Since"] != null && Count % 2 == 0) { return new HttpStatusCodeResult((int)HttpStatusCode.NotModified); } Response.Cache.SetExpires(DateTime.Now.AddSeconds(5)); Response.Cache.SetLastModified(DateTime.Now);   return Json(new { count = Count++ }, JsonRequestBehavior.AllowGet); }

The MVC action in the example above is only an example. In a real implementation, the server should be able to know whether the data has changed since the last time it was served or not.

Categories: Blogs

AgileSight, my new venture

Pablo Blog - Mon, 2012-02-06 14:05

Another important milestone in my career started three years ago when I joined Tellago. I convinced my friend Jesus to hire me, and I would eventually move to the United States with my family to work in the company.  That never occurred for some personal things, but I fortunately had a chance to create an excellent team of very talented people in Argentina. I started myself working remotely from Argentina, and the things went so well for the company that we end up hiring more than 15 great architects down here in Argentina.  Creating this team was a very interesting and completely new challenge in my career.

I also got involved in a lot of interesting projects, and what is more important, I had a chance to work and met great people, which is what it really worth it.

However, a month ago, I decided it was about time to start a personal project with a good friend of mine, and that’s how AgileSight was born. Although the initial conception of the company was to create software products, we will also offering software consulting and development services. I am definitely very excited to be part of this new venture and face all new kind of challenges ahead.

My first assignment in AgileSight couldn’t be better as I will be working in the next Web Mobile Guidance project (Liike project) with the Microsoft Patterns & Practices team.

Categories: Blogs

Claims Identity + C# 4.0 Dynamics

Leandro Boffi - Sun, 2012-02-05 21:30

In this post I want to share with you something that I always use when I work with claim-based identity using Windows Identity Foundation.

As you probably know, when you use claim-based identity in a project using WIF you have access to the user claims in the System.Thread.CurrentPrincipal.Identity property, but there is an small problem, it’s type is System.Security.IIdentity and to access to the claims you need to cast that property to Microsoft.IdentityModel.Claims.IClaimsIdentity so you end up with something like this in the middle of your app:

((IClaimsIdentity)Thread.CurrentPrincipal.Identity).Claims

That’s not sexy at all, and it gets worse if you need an specific claim, for example the email address of the user:

var user = ((IClaimsIdentity)Thread.CurrentPrincipal.Identity); var email = user.Claims.FirstOrDefault(x => x.ClaimType.Equals(ClaimTypes.Email, StringComparison.OrdinalIgnoreCase)) .Value;

You can solve this with a simple extension method something like GetClaimValue(string claimType), and you’ll get something like this, but is still not sexy:

var user = ((IClaimsIdentity)Thread.CurrentPrincipal.Identity); var email = user.GetClaimValue(ClaimTypes.Email);

Wouldn’t it be better to have something like this?

var email = user.Email;

Yes, you guessed, using C# 4.0 dynamics and a little of reflection, that’s possible, we simply need to create a class called DynamicIdentity that extends the DynamicObject class, and find in the ClaimTypes (or in any class we want) the value for the type requested using the property name to search. For example, if we write user.Email we are asking for all the  claims defined  with the claim type ClaimTypes.Email (“http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress”).

This is how the DynamicIndentity class looks like:

public class DynamicIdentity : DynamicObject { private ClaimTypeResolver claimTypeResolver; private IEnumerable<Claim> claims; public DynamicIdentity(IEnumerable<Claim> claims, ClaimTypeResolver typeResolver) { this.claims = claims; this.claimTypeResolver = typeResolver; } public override bool TryGetMember(GetMemberBinder binder, out object result) { var claimType = this.claimTypeResolver.Resolve(binder.Name); var claims = this.claims.Where(x => x.ClaimType.Equals(claimType, StringComparison.OrdinalIgnoreCase)); if (claims.Count() == 0) { throw new ArgumentException( string.Format("Claim with type '{0}' was not found", claimType)); } if (claims.Count() == 1) { result = claims.First().Value; return true; } result = claims.Select(x => x.Value).ToArray(); return true; } }

The ClaimTypeResolver class is responsible for resolving the Claim Type value based on the property name:

public class ClaimTypeResolver { private Type[] typesDefinition; public ClaimTypeResolver(Type[] typesDefinition) { this.typesDefinition = typesDefinition; } public string Resolve(string friendlyName) { foreach (var type in this.typesDefinition) { var field = type.GetField(friendlyName); if (field != null) { return field.GetRawConstantValue().ToString(); } } throw new ArgumentException( string.Format("Claim Type '{0}' was not found.", friendlyName)); } }

Notice that it receives an array with the types that contains the constants for your claim types.

Once we have that, we just need to create and extension method of the IPrincipal class that returns this dynamic object:

public static dynamic AsDynamic(this IPrincipal user) { var claims = ((IClaimsIdentity)user.Identity).Claims.AsEnumerable(); var resolver = new ClaimTypeResolver(new Type[] { typeof(ClaimTypes), typeof(MyCompanyClaimTypes), }); return new DynamicIdentity(claims, resolver); }

That’s all, this is the final experience for the developer:

var user = Thread.CurrentPrincipal.AsDynamic(); Console.WriteLine("Email: {0}", user.Email); foreach (var role in user.Role) { Console.WriteLine("Role: {0}", role); }

Download the code here!

Categories: Blogs

Rocking the Enterprise with Kinect: Slides and Recording

Jesus Blog - Wed, 2012-02-01 13:48
Thanks to everybody who attended our latest Tellago Technology Update webinar: “Rocking the Enterprise with Kinect”. We truly enjoyed the enthusiastic audience and the insightful feedback. You can find the slide-deck below and watch the recording at https...(read more)
Categories: Blogs

Capsela, the game that changed my life

Jose Romaniello Blog - Wed, 2012-02-01 09:00

In 1995 my parents did a trip to USA and they bought me as a gift an special game called Capsela. Just looking back I can realize how much this game changed my life and is for this reason that I decided to write an article about it (in spanish and english!).

2011-12-09_0050.png

I couldn't found a lot of information about this game in internet nowadays. About its origin, I couold say that it was designed and manufactured first by "Mitsubishi Pencil Co" in the 80's, then they gave the license to a company called "Play Jour" and since then as been manufactured by VTech, Kidology and other subsidiaries.

What is this game?

The game is about connecting capsules to create various kinds of "models". Each capsule has a different mechanical or electrical purpose. Those models are mostly vehicles for both water and land, although it is possible to build cranes, robots, water pumps and even a cleaner dust vacuum. While the game manual comes with a vast collection of photos with models you can create, much more interesting is to let your imagination flow and build things in your head, a "crawler crane vacuum"? sounds interesting.

Every model starts from a fundamental capsule that contains the motor and two terminals in which you have to "connect" the power wires from the batteries (which in turn is placed inside another capsule) or a switch.

Mechanical capsules are beautiful, with its gears inside those are some of the most common components that exist in the mechanical. The explanations that comes in the manual are beautiful as well:

2011-12-09_0050.png

Unfortunately, the manual I have is in three different languages German, Italian and Icelandic, and I can vaguely read some italian but I will do my best here with the help of Google Translate :)

  • Motor Capsule; The motor inside is fed with an external battery. If you want to change the direction of rotation, change the position of the battery wires. If you want to use the switch box, put the cables as shown in the figure. Be careful not wet the engine, risk of dammage.

  • Speed reduction to multiple state Capsule: This capsule reduces the speed of the shaft and at the same time it increases the torque or the rotational force. For a good use of the engine, it must be connected to the input shaft. If by error is placed to the output shaft, the motor will not move. To know which is the input shaft, rotate it with your finger. The input shaft is the easiest to rotate.

  • Gear shift Capsule: This capsule combines the function of changing the speed of the wheel cap and tooth in a single unit. This can reduce the shaft speed and change direction of the driving force directly at a right angle.

2011-12-09_0050.png

  • Planetary Gear Capsule: This capsule allows you to change the direction of the torque in right angle. If you install a sprocket shaft to the command it can be transmitted in three ways.

  • Internal Gear Capsule: this capsule changes the speed of the shaft without changing the direction of the command.

  • Rotating switch Capsule: while the shaft rotates, the switch is chaging to open and closed position. The figure shows how to put the wire and the battery.

  • Friction Capsule: this capsule was made to plug or unplug the command of the motor. The two gears could be unplugged with the two-point switch.

  • Transmission Capsule: this capsule could be connected into any other capsule to extend the gear without changing the prime mover.

Then you have lot of parts that can be connected to the aforementioned capsules, some of then in this picture:

2011-12-09_0050.png

To connect the capsules, you have to use an octogonal piece as shown in this picture:

2011-12-09_0050.png

Another interesting thing in the manual is this:

2011-12-09_0050.png

Which in my humble opinion summarizes a lot of years in the history of mechanical engineering.

Things you can assemble

With the capsules you can assemble these things:

2011-12-09_0050.png

2011-12-09_0050.png

2011-12-09_0050.png

2011-12-09_0050.png

2011-12-09_0050.png

2011-12-09_0050.png

Television commercial

I also found this tv spot (of the 80's I guess)

In this vide you can see even a remote control that I never had. I read also in wikipedia that there was a model with an interface to Commodore 64, Lego Mindstorms predecessor.

How does this game changed me?

I do not study Mechanical Engineering. However this open my mind, the freedom of being able to invent things. I learned for instance, that with certain components I could change the energy of the motor, and the relation between speed and power, etc.

This awoke in me the desire and interest in engineering. Looked back and I find many similarities between my current job as a software developer and this game. In fact any engineering is like this game, "here are your tools and these are the blocks you can use, now builds what you want! The only limit is your imagination!". Maybe now is what someone else wants rather than "whatever you want". But as many of the best professionals I've worked it happens that our work becomes our hobby and that's when we are back to our imagination, like the 10 years old Jose sitting in his room, thinking what to invent .

My mother kept some of the parts of the toy even if I ignore the game for so long, and two years ago, I found in local website a person selling his capsela. Even if this was an smaller set (less pieces) it was in perfect condition. Now I have two capselas, and sometimes we build really crazy things with my 6yo daughter.

Last but not least, I would like to congratulate the people who designed this toy, I would be really happy if any of them read this and thank my parents, Gines and Franca, for having bought this at Toys "R" Us in 1995.

Categories: Blogs

Capsela, el juego que cambió mi vida

Jose Romaniello Blog - Tue, 2012-01-31 22:46

En 1995 mis padres realizaron un viaje a Estados Unidos y como regalo me trajeron un juego bastante peculiar llamado Capsela. Solo mirando hacia atras puedo darme cuenta del impacto que tuvo este juego en mi vida y es por eso que hoy decidí escribir un artículo en forma de tributo.

2011-12-09_0050.png

Poca información he encontrado en internet acerca de este juego en estos días. Sobre su origen podría decir que fue diseñado y fabricado en principio por "Mitsubishi Pencil Co" en la decada de 1980, luego se le dió la licencia a una empresa llamada "Play Jour" y desde ese momento fue fabricado por VTech, Kidology y algunas otras subsidiarias.

¿En qué consiste el juego?

El juego consiste en interconectar cápsulas, con diferentes propósitos mecánicos o eléctricos, para crear diferentes tipos de "modelos". Estos modelos son en su mayoría vehículos tanto para el agua como para la tierra, aunque también es posible construir grúas, robots, bombas de agua e incluso una aspiradora de polvillo. Si bien el manual del juego trae una basta colección de gráficos con cada uno de los modelos que se pueden crear, mucho mas interesante es dejar volar la imaginación y armar lo que nos plazca, una "grúa aspiradora de polvillo con forma de oruga"? suena interesante.

Todo modelo parte desde una cápsula fundamental que contiene un motor y dos terminales en donde se "conectan" los cables de alimentación desde las pilas (que a su vez se colocan dentro de otra cápsula) o desde una llave que además es inversora pilas-llave-motor.

Las cápsulas mecánicas son preciosas, con sus engranajes adentro forman algunos de los componentes más comunes que existen en las cosas mecánicas que nos rodean. La explicación en el manual es algo imperdible también, por ejemplo estas tres:

2011-12-09_0050.png

Lamentablemente, el manual que tengo en este momento esta en tres idiomas Alemán, Italiano e Islandés, y ninguno es mi fuerte. Pero voy a hacer mi mejor esfuerzo:

  • Cápsula motor: El motor incorporado es alimentado de la pila externa. Sí usted desea cambiar el sentido de la rotación del motor, invierta la posición del cable de la batería. Sí usted desea usar la caja del interruptor, colocar los cables como se indica en el diseño. Estar bien atento de no mojar el motor, corre el riesgo de dañarlo.

  • Cápsula de reducción de velocidad a estado multiple: Esta cápsula reduce la velocidad del eje, y al mismo tiempo aumenta el momento de torsión o la fuerza de rotación. Para un buen funcionamiento del motor, el mismo debe ser conectado al eje de entrada. Si por error es colocado al eje de salída, el motor no se moverá. Para saber cual es el eje de entrada, hágalo rotar con el dedo. El eje de entrada es el que rota fácilmente.

  • Cápsula de cambio de la marcha: Esta cápsula combina la función del cambio de la velocidad con la cápsula de la rueda y diente en una sola unidad. De este modo se puede reducir la velocidad del eje y cambiar la dirección de la fuerza motriz directamente en angúlo recto.

2011-12-09_0050.png

  • Cápsula engranaje planetario: esta cápsula permite cambiar el sentido de la fuerza motríz en angúlo recto (90°). Sí usted instala un eje a la rueda dentada el comando puede ser transmitido en tres sentidos.

  • Cápsula engranaje interno: esta cápsula cambia la velocidad del eje sin cambiar el sentido del comando.

  • Cápsula del interruptor rotante: cuando el eje gira, el interruptor es colocado alternativamente en posición abierta y cerrada. El diseño muestra como debe colocar la lámpara con la pila.

  • Cápsula de fricción: esta cápsula fue concebida para conectar o desconectar el comando del motor. Los dos engranajes pueden ser desconectados mediante el dispositivo de dos puntos.

  • Cápsula de transmisión: esta cápsula puede ser conectada a cualquier otra capsula con el objetivo de extender la acción del cambion de la marcha sin cambiar el engranaje de la fuerza motríz.

Luego vienen un monton de partes que pueden ser conectadas a dichas cápsulas, algunas de ellas se pueden ver en esta imágen:

2011-12-09_0050.png

Para unir cada cápsula se utiliza una pieza de forma octogonal como se indica en esta figura:

2011-12-09_0050.png

Otra perla del manual es este gráfico:

2011-12-09_0050.png

Que en mi opinión sintetiza muchisimos años de la historia de la mecánica.

Lo que se pueden armar

Con las partes antes mencionadas se puede armar este tipo de cosas:

2011-12-09_0050.png

2011-12-09_0050.png

2011-12-09_0050.png

2011-12-09_0050.png

2011-12-09_0050.png

2011-12-09_0050.png

El manual de instrucciones trae muchos ejemplos más pero no es mi intención aburrir.

Comercial de televisión

También encontré esta otra perlita, un comercial de TV de los años 80' supongo.

En este video se puede ver incluso un control remoto que yo nunca tuve. Como así también leí en wikipedia que se fabricó un modelo que tenía una interfaz para conectar a Commodore 64, un antecesor Lego Mindstorms.

¿Cómo me afecto este juego?

Por empezar no estudie ingeniería mecánica. Sin embargo me abrió la cabeza, la "libertad" de poder inventar juguetes. Aprendí que por ejemplo, con ciertos componentes podía transformar la energía del motor, la relación entre la velocidad y la fuerza, etc.

Despertó en mí un deseo e interés por la ingeniería. Visto hacia atrás, encuentro muchas similitudes entre mi trabajo actual como desarrollador de software y este juego. De hecho cualquier ingeniería se asemeja; "aquí están tus herramientas y estos son los bloques que puedes utilizar, ahora construye lo que quieras! el único límite es tu imaginación!!". Tal vez ahora no se aplica "lo que quieras", mas bien lo que otro quiera. Pero como a muchos de los mejores profesionales con los que he trabajado les sucede, nuestro trabajo se convierte en nuestro hobby y es ahí cuando dejamos volar nuestra imaginación de nuevo, al igual que el José de 10 años sentado en su habitación, pensando que inventar.

Mi mamá guardó todas las partes del juego a pesar de que yo las ignoré por mucho tiempo, y hace dos años ya, encontré una persona en mercadolibre que vendía el suyo. A pesar de que era una versión que traía menos partes que el que ya tenía y de que había sido usado, estaba en excelentes condiciones. Ahora tengo 2 Capsela, y a veces armamos cosas muy alocadas con mi hija Valentina (6 años).

Para terminar este artículo, me gustaría felicitar a las personas que diseñaron este jueguete, moriría de felicidad si alguno de ellos leyera esto, y agradecer a mis padres, Gines y Franca, por haberlo comprado en Toys"R"Us en 1995.

Categories: Blogs

The rise of Single Page Applications (SPA) in Web Mobile

Pablo Blog - Fri, 2012-01-27 19:34

Limited connectivity is one of the main challenges in web mobile. The stateless nature of http causes that  content  and associated static files like scripts or images be transmitted over the wire every time a page is fully refreshed (assuming http caching is not implemented correctly). Diverse techniques have emerged over the years to solve part of that problem by using the browser AJAX support. One of these techniques, which drastically changed the way we develop web applications is know as single page applications.

A single page application design assumes that good part of the website layout is fixed and there are a few placeholders for showing dynamic content. The layout and associated files can be download once, and the rest can be dynamically changed using AJAX calls to a backend Web API.    

There are also a few improvements that can be made like caching all the static content and associated files, and use client templates to remove all the overhead involved with downloading html markup on every AJAX call. By using client templates (e.g. JQuery templates, JSRender, Mustache) , only the data (usually JSON data) is negotiated with the backend, and the templates can be cached as static content as well.

In the area of web mobile, it is pretty important to optimize the use of the available bandwidth to support scenarios where the connectivity is very unreliable or limited data plans are used. This is exactly where single page applications make a lot of sense. As this kind of application makes a heavy use of javascript for DOM manipulation, it might not be ideal for all kind of mobile devices (the device should support DOM manipulation and XHR).

I personally think this kind of architecture for a web application will become a common norm now that we have devices with web support everywhere.

Categories: Blogs

Installing and Configuring PeopleSoft Adapter for BizTalk Server 2010

BizTalkUnleashed Blog - Wed, 2012-01-25 22:00

Architecture of PeopleSoft Adapter:

The BizTalk PeopleSoft Adapter is based on the BizTalk Server Adapter Framework. More info: How the Adapter Is Designed: The Adapter Framework. The PeopleSoft adapter basically communicates with the PeopleSoft Component Interfaces via the PeopleSoft JOLT protocol (over TCP/IP). The adapter communicates with PeopleSoft system by receiving a XML message which is later encapsulated into a SOAP request using the PeopleSoft psjoa classes. With this connection we can get the metadata to call into the existing Component Interfaces and generate the API schemas and use them within BizTalk Server for mapping, orchestrations at design time and runtime. According to Microsoft, if you need to have PeopleSoft Enterprise to initiate the call to BizTalk Server, they recommend using the HTTP adapter. More info : Creating a PeopleSoft HTTP Host and Port

PS Adp 1

More detailed information on PeopleSoft Adapter Architecture can be found on MSDN.


Requirements for PeopleSoft Adapter:

  • BizTalk Server Enterprise Adapters installed and configured and of course BizTalk Server 2010 installed and configured.
  • Java Development Kit (JDK) 1.4.2 or later.
  • Access to the PeopleSoft Application Designer to deploy Component Interface. The PeopleSoft Application Designer does not have to be on the BizTalk server.

Installing BizTalk Server Enterprise Adapters:

  • Open the BizTalk Server 2010 setup and click Install Microsoft BizTalk Adapters.

BTS1

BTS2

    • Install Adapters packs for all the 4 Steps.

BTS3

BTS4

BTS5

BTS6

BTS7

BTS8

BTS9

  • This concludes the installation the BizTalk Adapters for Enterprise Applications. Don’t worry about the warning in Step1.

BTS10


Configuring PeopleSoft Adapter for BizTalk Server:

  • Open BizTalk Server Administration Console –> Platform Settings –> Adapters –> Right Click –> New –> Adapter

BTS11

  • In the new window, choose name as PeopleSoft and from the adapter dropdown choose PeopleSoft Enterprise. Click Apply –> OK and restart your Host Instances. Now you can see the PeopleSoft Adapter as the installed BizTalk Adapters.

BTS12

BTS13

  • This concludes the configuration of PeopleSoft adapter on the BizTalk side. Next is to create a Component Interface on the PeopleSoft side though which BizTalk PeopleSoft adapter can communicate.

Configuring a New Component Interface for PeopleSoft:

Environment

- PeopleSoft PeopleTools 8.52

- PeopleSoft Enterprise HRMS 9.0

- Oracle Web Logic Server 10.3.4.0

- Tuxedo 10gR3

- JRockit JDK R28.1

Step1: Creating a New Component Interface:

  • Go to the Server where you have PeopleSoft Enterprise Application installed.
  • Go to Start –> All Programs –> PeopleSoft (can differ according to version you have installed) –> Application Designer. Log in with your PeopleSoft user ID.

PS Adp 2

  • On the File menu, click New. In the New dialog box, select Component Interface.

PS Adp 3

  • Click Select on the next window and it will show list of current CI. Select any Component Interface which does not have any keys. After you select the appropriate component, you see a message asking if you want the fields exposed in the selected component to become the default properties of the Component Interface.

PS Adp 4

PS Adp 5

  • Click Yes to confirm the Default Property Definitions or No if you don’t want any properties initially created.

PS Adp 6

  • On the File menu, click Save As. In File Name, enter GET_CI_INFO, and then click OK.

PS Adp 7

  • Right-click any method of your new Component Interfaces, and then click View PeopleCode. A new blank window will pop up.

PS Adp 8

  • Copy and paste the contents of <PeopleSoft installation directory>\PeopleSoft Enterprise\config\get_ci_info.pc into the window. Open the file in notepad and copy the contents of it.

PS Adp 10

PS Adp 9

  • On the File menu, click Save. You now have a new Component Interface.
  • Just to verify if you perfomed the steps correct. Close the Application Designer. Reopen Application Designer and Log in with your PeopleSoft user. Go to File –> Open –> Component Interface and browse to GET_CI_INFO and open it. You should see something similar as shown below.

PS Adp 11

Step2: Set the PeopleSoft Component Interface security:

In the below steps, the Permission lists, Roles and User Profile are just selected randomnly to display the steps. Please select the appropriate Permission List, Roles and User Profile according to your use and accessibility. Highly recommend setting up this security with a PeopleSoft Administrator person or a PeopleSoft expert.

  • Sign in to PeopleSoft Web Portal.

1

  • Select PeopleTools, Security, Permissions & Roles, Permission Lists.

2

  • Click Search, select the relevant Permission List, and click the appropriate list hyperlink. The Permission List pane opens on the right.

3

  • Click the right arrow next to the Sign-on Times tab to display the Component Interfaces tab. Click the Component Interfaces tab.

4

  • Click the + button to add a new row to the Component Interfaces list.

5

  • Select the GET_CI_INFO component interface and click Edit.

6

7

  • Click Full Access (All) to set the methods to Full Access. Click OK.

8

  • Scroll down to the bottom of the Component Interfaces window and click Save.

9

  • Select PeopleTools, Security, Permissions & Roles, Roles. Click Search, select the relevant Role and click the appropriate list hyperlink.

10 

  • The Role pane opens on the right. Click the Permission List tab.

  • Click the + button to add a new row to the Permission List.

  • Select the GET_CI_INFO Permission List.

  • Scroll down to the bottom of the Roles window and click Save. [Save as GET_CI_ROLE]

11

  • Select PeopleTools, Security, User Profiles, User Profiles.

  • Click Add New Value, type BizTalk into the text box, and click Add to display the General tab

12

  • Select a Symbolic ID in the drop-down box.

  • Type a Password and Confirm Password.

  • Choose an appropriate Navigator Homepage.

  • Choose an appropriate Process Profile.

  • Choose an appropriate Primary Permission List for the Primary field.

  • Choose an appropriate Row Security Permission List for the Row Security field.

13

  • Click the Roles tab.

  • Click the + button to add a new row to the Roles list.

  • Select the GET_CI_INFO Role.

  • Select the PeopleSoft User Role.

  • Select the Standard Non-Page Permissions Role.

  • Scroll down to the bottom of the User Profile window and click Save.

14

Step3: Testing the Component Interface:

  • Start  PeopleSoft Application Designer. Click File, Open and select Definition = Component Interface.

  • Select GET_CI_INFO CI from the list of Component Interfaces.

15

  • After opening GET_CI_INFO, right-click anywhere in the right pane of your Component Interface definition and select Test Component Interface.

    The Component Interface Tester dialog box appears.

16

  • GET_CI_INFO should not contain any keys. If keys are present, you need to return to Application Designer and remove them.

This concludes the set up of the GET_CI_INFO Component Interface needed to communicate with BizTalk Server. Open-mouthed smile


In the next coming blog posts we will see how we can generate metadata with this GET_CI_INFO Component Interface.


Regards,

Vishal Mody Winking smile


PS: Reference from MSDN article : Microsoft BizTalk Adapters for PeopleSoft

 

Categories: Blogs

Implementing resource oriented controllers in ASP.NET MVC

Pablo Blog - Wed, 2012-01-25 15:49

One common problem with the naming convention and default routing mechanism in ASP.NET MVC is that we tend to group actions in a controller for sharing an URL space.  This basically leads to complex controllers with a lot of unrelated methods that break the SOLID principles.  Too many responsibilities in a simple class affects maintainability in the long run and causes secondary effects that complicates unit testing. For example, we usually end up with class constructors that receives too many dependencies as it is discussed here in SO.

A service façade or a service locator are not the solution for this problem either. I personally think the solution here is to use controllers with fewer responsibilities and define the right routing in case you want to share the URL space. There are some discussions around the idea of using what was called controller-less actions, in which a controller only performs a single thing. Without going to that extreme, we can use a more resource oriented approach for assigning responsibilities to a controller.  A resource in http is uniquely identified by an URI  and can be manipulated through an unified interface with http verbs. Although some verbs do not make much sense when working with a browser like “delete” or “put”, we can replace those with “post”.

Implementing a delete action with an http get is definitely wrong, as an http get should be idempotent.

Let’s start an example by defining a simple scenario for managing a set of customers. We can initially define two resources, Customers for performing actions in the collection, and Customers/{id} for performing actions in a single customer. Although they both share the same URL space “Customers”, it does not mean we need to implement all the functionality in a single controller called “Customers”. We can still have a “CustomersController” for the collection, and a “CustomerController” for the individual customers. We can use routing for share the same URL and still forward the requests to the right controller.

We can define the following operations in the “CustomersController”,

  • Add (GET Customers/Add): Retrieves the Html form representation for creating a new customer
  • Add (POST Customers/Add): Receives a representation (encoded in the form) for creating a new customer in the collection
  • Delete (POST Customers/{id}/Delete: Removes a customer from the collection
  • Index (GET Customers): Retrieves a Html view representing a list of customers
public class CustomersController : Controller { ICustomerRepository repository;   public CustomersController() : this(new CustomerRepository()) { }   public CustomersController(ICustomerRepository repository) { this.repository = repository; }   public ActionResult Index(string filter = null) { IEnumerable<Customer> customers = null;   if (!string.IsNullOrEmpty(filter)) { customers = this.repository.GetAll() .Where(c => c.FirstName.Contains(filter) || c.LastName.Contains(filter)); } else { customers = this.repository.GetAll(); } return View(customers); }   [HttpGet] public ActionResult Add() { return View(); }   [HttpPost] public ActionResult Add(Customer customer) { if(ModelState.IsValid) this.repository.Add(customer);   return RedirectToAction("Index"); }   [HttpPost] public ActionResult Delete(int id) { this.repository.Delete(id);   if (Request.IsAjaxRequest()) return new HttpStatusCodeResult((int)HttpStatusCode.OK);   return RedirectToAction("Index"); }   }

The “CustomerController” can have the following operations:

  • Get (GET Customers/{id}): Retrieves an Html form representing an specific customer
  • Update (POST Customers/{id}): Receives a representation (encoded in the form) for updating the customer
public class CustomerController : Controller { ICustomerRepository repository;   public CustomerController() : this(new CustomerRepository()) { }   public CustomerController(ICustomerRepository repository) { this.repository = repository; }   [HttpGet] public ActionResult Get(int id) { var customer = this.repository.GetAll() .Where(c => c.Id == id) .FirstOrDefault();   if (customer == null) return new HttpStatusCodeResult((int)HttpStatusCode.NotFound);   return View(customer); }   [HttpPost] public ActionResult Update(Customer customer) { if (ModelState.IsValid) this.repository.Update(customer);   return RedirectToAction("Index", "Customers"); }   }

This is how the routing table looks like,

public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}");   //This map is required so the Add segment is not used as {id} routes.MapRoute( name: "CustomerAdd", url: "Customers/Add", defaults: new { controller = "Customers", action = "Add" } );   routes.MapRoute( name: "CustomerGet", url: "Customers/{id}", defaults: new { controller = "Customer", action = "Get" }, constraints: new { httpMethod = new HttpMethodConstraint("GET") } );   routes.MapRoute( name: "CustomerUpdate", url: "Customers/{id}", defaults: new { controller = "Customer", action = "Update" }, constraints: new { httpMethod = new HttpMethodConstraint("POST") } );   routes.MapRoute( name: "MVC Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } );   }

You can override the default route for “Customers/{id}” for getting or updating an specific customer by using an http method constraint. I also added the first  route for adding a new customer so the “Add” segment is not used as the “{id}” wildcard.

As you could see, we could split all the responsibilities in two controllers, which look simpler at first glance. In conclusion, you don’t need to assume the same URL means the same controller.

The “delete” action is implemented as an http post. This can be sent from the browser by using an Ajax call or a Http form. For example, the following code shows how to do that using a JQuery Ajax call.

@Html.ActionLink("Delete", "Delete", new { id = item.Id }, new { @class = "delete" }) <script type="text/javascript" language="javascript"> 1:  2: $(function () { 3: $('.delete').click(function () { 4: var that = $(this); 5: var url = that.attr('href'); 6:  7: $.post(url, function () { 8: alert('delete called'); 9: }); 10:  11: return false; 12: }); 13: });</script> The code is available for download from here
Categories: Blogs

Hide passed tests by default in Qunit

Jose Romaniello Blog - Wed, 2012-01-25 14:37

If you are using qunit and you are tired of the 392019321 passed tests output in your browser, there is a checkbox at the top to hide all passed tests. Unfortunately after you refresh the page you will lose this.

Don't worry I have a snippet for you, insert this at the botton of your test harness page (inside a script block):

$(document) .ready(function(){ $('#qunit-tests').addClass('hidepass'); }) .delegate("#qunit-testrunner-toolbar", "DOMNodeInserted", function(e){ $("#qunit-filter-pass").attr("checked", true) }) .delegate("#qunit-filter-pass", "click", function(e){ e.stopPropagation(); var newValue = $(this).is(":checked"); $('#qunit-tests').toggleClass('hidepass', newValue); });
Categories: Blogs

Installing PeopleSoft HRMS 9.0 on Windows Server 2008 with SQL Server 2008 &ndash; Part 3

BizTalkUnleashed Blog - Tue, 2012-01-24 22:20

Step 9: Completing the Database Setup:

This step is a very critical step and should performed with very much attention. Below mentioned steps are the ones which I thought were required for the environment I was building but I very highly recommend that you perform this step from the Oracle Installation document which can be found here. Look at Chapter 7 in this document. 

Updating PeopleTools System Tables:

  • Here PS_HOME is the directory where you have installed your PeopleTools. In our case its C:\PT852 directory.
  • Got to PT852\scripts and run rel851u.sql and rel852u.sql sql scrips.
  • Edit and run the grant.sql script in the PS_HOME\scripts directory. This will grant permissions to the CONNECTID. Run the script as a user with Microsoft SQL Server system administrator privileges.
  • Invoke Data Mover by running PS_HOME\bin\client\winx86\psdmt.exe. The PeopleSoft Logon window appears.Log on using a valid PeopleSoft Operator ID, such as PS for HRMS.
  • Run the storeddl.dms Data Mover script in the PS_HOME\scripts directory.
  • Invoke Data Mover by running PS_HOME\bin\client\winx86\psdmt.exe. The PeopleSoft Logon window appears. Log on using the ACCESSID you specified when you created your Data Mover scripts with the Database Setup program. This will start Data Mover in bootstrap mode.
  • Run the msgtlsupg.dms Data Mover script in the PS_HOME\scripts directory. This will update the PeopleSoft PeopleTools messages in your database.

Updating PeopleTools Database Objects

  • Launch Appplication Designer and sign on to your databse with a valid PeopleSoft UsedID.
  • Select Tools, Copy Project, From File.
  • In the resulting dialog box, change the import directory to PS_HOME\projects, select PPLTLS84CUR from the list of projects and click the Select button.

PostDB1

  • The Copy From File dialog box appears. Select all object types and then click the Copy button. When the progress window disappears, the project has been copied

PostDB2

Altering PeopleTools Tables:

  • Launch Application Designer with a valid PeopleSoft user ID and sign on to the installed database. Select File, Open. Select Project, enter PPLTLS84CUR in the name dialog box, and click OK.
  • Select Build, Project.

PostDB3

  • Select Create Tables and Alter Tables in the Build Options region.
  • Select Build script file in the Build Execute Options region.
  • Click Setting. The Build setting dialog box appears:

PostDB4

PostDB5

PostDB6

  • Click OK.The Build dialog box reappears. Click Build. Click Close when the process is completed.

Updating the PeopleTools System Data:

  • Invoke Data Mover by running PT852\bin\client\winx86\psdmt.exe. The peoplesoft logon window appears.
  • Log on with the AccessID and Password.
  • Run the DataMover scripts from the application database version. In our case run Pt851tls.dms and pt852tls.dms
  • Run the pslanguages.dms Data Mover script in the PS_HOME\scripts directory.
  • Run the tlsupgnoncomp.dms Data Mover script in the PS_HOME\scripts directory.
  • Open Data Mover using a valid PeopleSoft Operator ID, such as PS for HRMS
  • Run the msgtleng.dms Data Mover Script in the PS_HOME\scripts directory.
  • Run the ptstreng.dms Data Mover script in the PS_HOME\scripts directory.
  • Run the storept.dms Data Mover script in the PS_HOME\src\cbl\base directory.
  • Run the ptdefnsec.dms Data Mover script in the PS_HOME\scripts directory.
  • Run the createvw.dms Data Mover script in the PS_HOME\scripts directory.

This concludes post database configurations.


Step10: Configuring the Application Server on Windows:

  • Go to command prompt and go the the location C:\PT852\appserv
  • Type PSAdmin and click enter
  • Select 1 for Application Server and press enter.
  • Specit 2 to Create a domain and press enter.
  • Enter the domain name to create: say HR84
  • Specify 4 for small if this is your initial domain installation and press Enter.
  • After the system creates the domain, this prompt appears:
  • Would you like to configure this domain now? (y/n) [y] :

Enter y. The PeopleSoft Application Server Administration menu appears with a Quick-configure menu

similar to this:

---------------------------------------------------------

Quick-configure menu -- domain: HR84

---------------------------------------------------------

Features Settings

========== ==========

1) Pub/Sub Servers : No 15) DBNAME :[HR84]

2) Quick Server : No 16) DBTYPE :[MICROSFT]

3) Query Servers : No 17) UserId :[QEDMO]

4) Jolt : Yes 18) UserPswd :[QEDMO]

5) Jolt Relay : No 19) DomainID :[TESTSERV]

6) WSL : No 20) AddToPATH :[c:\Program FilesÞ

\Microsoft SQL Server\100\Tools\Binn]

7) PC Debugger : No 21) ConnectID :[people]

8) Event Notification : Yes 22) ConnectPswd :[peop1e]

9) MCF Servers : No 23) ServerName :[]

10) Perf Collator : No 24) WSL Port :[7000]

11) Analytic Servers : Yes 25) JSL Port :[9000]

12) Domains Gateway : No 26) JRAD Port :[9100]

13) Load config as shown

14) Custom configuration

h) Help for this menu

q) Return to previous menu

HINT: Enter 15 to edit DBNAME, then 13 to load

Enter selection (1-26, h, or q):

· Press 6 and Enter this is enable WSL

· Press 8 and Press Enter this will disable Event Notifications.

· Press 17 and type PS

· Press 18 and type PS

· Press 21 and Type PSCID ( This will be your connect ID)

· Press 22 and Type P@ssw0rd (This will be your connedID Password)

· Press 13 and this will Load the configuarations which we configured above.

  • In the next menu, select 1 to Boot this Domain
  • In the next menu, select 1 for Serial Boot and 2 for Parallel Boot. This will boot the domain which we created above.
  • Next we will be doing PIA installation so keep the App server up and running.
  • Check the screenshots for your references.

AS1

AS2

as3

as5

  • This concludes configuration of Application Server

 


Step11: Setting up the PeopleSoft Pure Internet Architecture(PIA):

  • Go to PS_HOME\setup\PsMpPIAInstall and run setup.bat.
  • Click Next on the Welcome to the Installation Wizard for PeopleSoft Internet Architecture window.
  • Next follow the instruction’s as shown in the screenshots below.

PIA1

PIA2

PIA3

PIA4

PIA5

PIA6

PIA7

PIA8

PIA9

PIA10

PIA11

PIA12

PIA13

  • This will create a PIA domain. Next step is to start this Domain.
  • GO to Command Prompt and go to C:\PT852\appserv location
  • Type psadmin and Press Enter.
  • Specify 4 for Web PIA Server
  • Select 1 for Administer a domain.
  • Select the domain you want to administer by entering the appropriate number.
  • To start a web server domain, enter 1, Boot this domain.
  • The boot command invokes the startPIA.cmd script, and you see the progress and a status message on the console window.

Starting the domain..................

The domain has started.


Step12: Accessing the PeopleSoft Application:

PS Sign On

PS HomePage

This concludes the installation and configuration of PeopleSoft HRMS 9.0 Application.

Categories: Blogs

Installing PeopleSoft HRMS 9.0 on Windows Server 2008 with SQL Server 2008 &ndash; Part 2

BizTalkUnleashed Blog - Tue, 2012-01-24 21:27

Step6: Installing People Tools 8.52:

  • After you download and extract the PeopleSoft PeopleTools installation files you can find the installer in PS_INSTALL/disk1. Launch the installer using setup.bat. Click Next when you see the Welcome screen for PeopleTools 8.52.
  • Follow the steps as shown in the screen shots below.

clip_image001

clip_image002

clip_image003clip_image004

clip_image005

clip_image006

clip_image007

clip_image008

clip_image009

clip_image010

clip_image011

clip_image012

clip_image013

  • This concludes the installation of PeopleTools 8.52.

Step 7: Installation PeopleSoft Application Software (HRMS 9.0):

  • Download and extract the step up files at PS_APP_HOME location on C:\.
  • Launch the installer with Setup.bat.
  • Follow the instructions as shown in the screenshots below.

clip_image015

clip_image017

clip_image019

clip_image021

clip_image023

clip_image025

clip_image027

clip_image029

  • This concludes the installation of PeopleSoft HRMS 9.0

Step8: Installing and configuring PeopleSoft Databases:

  • Go to the location C:\PT853\setup\PsMpDbInstall, double click setup.exe
  • In the welcome screen click Next to continue and follow the instructions as shown in the screenshot below.

clip_image002[4]

clip_image004[4]

clip_image006[4]

clip_image008[4]

clip_image010[4]

clip_image012[4]

clip_image014

clip_image016

clip_image018

clip_image020

clip_image022

clip_image024

clip_image026

clip_image028

clip_image030

clip_image032

Next steps continued in Part 3.

Thanks,

Vishal Modi

Categories: Blogs

Installing PeopleSoft HRMS 9.0 on Windows Server 2008 with SQL Server 2008 &ndash; Part 1

BizTalkUnleashed Blog - Tue, 2012-01-24 21:13

Environment what we are building consists of:

    • Operating System: Windows Server 2008 SP2.
    • Database Server: SQL Server 2008 with SP2.
    • PeopleSoft Application: PeopleSoft Enterprise Human Resources Management System and Campus Solutions 9.0
    • PeopleTools: PeopleSoft PeopleTools 8.52
    • Web Server: Oracle Web Logic Server 10.3.4

The machine name given for this environment is WIN2K8 and currently only 1 user, the default one which is Administrator and it is the local admin.

The below steps are performed with reference to the installation document of PeopleTools 8.52 on Microsoft SQL Serer provided by Oracle which can be found here. This document is indeed very good and describes everything in very much details. Only drawback is that it is like 700 pages document and very tedious to go through and perform steps. Hence thought of writing same instruction set but in bit easy format and more screenshots. Although, if you are not short of time and you really want to understand the installation and how each piece of software goes hand in hand with other then I highly recommend performing the installation with the Oracle document.


Step1: Download and install SQL Server 2008 with SP2:

  • Minimum requirement is Service Pack 2. If you have SP2 installed then you should see the SQL Server Native Client version as 2007.100.4000.00 as shown below in the screenshot. As of date, the latest Service Pack out for SQL Server 2008 is SP3 so even if you install SP3 then it works.

ODBC


Step2: Download all software required from Oracle

  • Go to Https://edelivery.oracle.com and sign in with your Oracle Account. If you do not have one, you can easily create one and its free registration.

edelivery

  • On the Media Pack Search Page select Product Pack as PeopleSoft Enterprise and Platform as Microsoft Windows x64.

PS Ent X64

  • On the next page select PeopleSoft Human Resources Management System and Campus Solutions 9.0 Media Pack and select Continue.

PS HRMS 9.0

  • On the next page download the following Softwares.

o PeopleSoft Enterprise Human Resources Management System and Campus Solutions 9.0: Feature Pack - March 2011

o PeopleSoft Enterprise Human Resources Management System and Campus Solutions 9.0 Supplemental Installation Information (Revision 3)

o PeopleSoft PeopleTools 8.52 Disc 1 of 3

o PeopleSoft PeopleTools 8.52 Disc 2 of 3

o PeopleSoft PeopleTools 8.52 Disc 3 of 3

o Tuxedo 10gR3 for MS Windows Server 2008 w/MS VS 2008 x86 32-bit

o JRockit JDK R28.1 for Java SE 6 with JRockit Mission Control 4.0.1 for Microsoft Windows (64-bit x86)

o Oracle WebLogic Server 11gR1 (10.3.4) Generic and Coherence


Step3: Installing JRockit for Microsoft Windows:

  • Unzip the downloaded file and double click the setup file. Click Next on the Welcome screen window.

JRockit1_thumb5_thumb

  • Change the installation directory to C:\Program Files\Java\jrockit-jdk1.6.0_20-R28.1.0-4.0.1 and click next

JRockit2_thumb1_thumb

  • Keep the default values on all other pages and as shown in below screen shots.

JRockit3_thumb1_thumb

JRockit4_thumb1_thumb

JRockit5_thumb1_thumb

JRockit6_thumb1_thumb

JRockit7_thumb1_thumb

  • This concludes the installation of JRockit.

Step4: Installing Oracle WebLogic on Windows:

  • Save the installation file wls_generic.jar from Oracle EDelivery in the directory called WLS_Install on C:\
  • Open a command prompt and go to WLS_INSTALL.
  • Set the environment variable JAVA_HOME to be the location where you installed the JRockit and Use the following command to launch the installer.

WLS-1_thumb7_thumb

set JAVA_HOME=”C:\Program Files\Java\jrockit-jdk1.6.0_20-R28.1.0”

%JAVA_HOME%\bin\java -jar wls1034_generic.jar -mode=GUI -log=C:\WLS_Install\Wls1034Install.log

WLS-1_thumb15_thumb

  • Wait for few seconds or also this might take few minutes and the Oracle WebLogic Installer Window will come up. Follow the instructionas as shown in the screenshots for next installation steps.

WLS-2_thumb1_thumb

WLS-3_thumb1_thumb

Remove the check box which says “I wish to receive security updates via My Oracle Support” . And click yes to remain uninformed for next 2 windows.

WLS-4_thumb1_thumb

WLS-5_thumb1_thumb

WLS-6_thumb1_thumb

WLS-7_thumb1_thumb

WLS-8_thumb1_thumb

WLS-9_thumb1_thumb

WLS-10_thumb1_thumb

WLS-11_thumb1_thumb

WLS-12_thumb1_thumb

  • This concludes the Installation of Oracle Web Logic Server 10.3.4.0

Step5: Installing Oracle Tuxedo:

  • Save the zip file to a temporary directory on your local system, referred to in this documentation as TUX_INSTALL.. Extract the files into TUX_INSTALL.
  • First you need to designate an existing user or create a new user such as TUXADM to be the Application Server Administrator. The Application Server Administrator and not the Windows Administrator. This user will install Oracle Tuxedo. The designated user must be a local Microsoft Windows administrator and must have full system privileges. The PeopleSoft PeopleTools 8.52 program for the Oracle Tuxedo installation creates a new service for Microsoft Windows called “ORACLE ProcMGR V10gR3 with VS2008” for which you need administrator privileges. Administrator rights are required since system registry settings are updated. Once this new service is created, you must reboot to start it.
  • To designate the Application Server Administrator:

1. To add the user, add the user ID by choosing Start, Settings, Control Panel, Administrative Tools, Computer Management, Local Users and Groups.

2. Expand Local Users and Groups.

3. If the user ID does not yet exist, highlight the Users folder, and select Action, New User.

4. On the New User dialog box, specify the information for the new account. Make sure to deselect the User must change password at next logon check box.

5. Expand the Groups folder.

6. Right-click the Administrators group, and select All Tasks, Add to Group, Add.

7. Click Locations to select the local machine or the network domain in which you created the new user.

8. Enter the new user name you created in the object names box.

9. Click OK, and click Apply and OK again to accept the changes.

  • Double-click TUX_INSTALL\tuxedo10gR3_32_win_2k8_x86_VS2008.exe to begin the installation process. Click OK on the initial window.
  • Follow the steps shown in screenshots below.

tux-1_thumb1_thumb

tux-2_thumb1_thumb

tux-3_thumb1_thumb

tux-4_thumb1_thumb

tux-5_thumb2_thumb

tux-6_thumb1_thumb

tux-7_thumb1_thumb

tux-8_thumb1_thumb

tux-9_thumb2_thumb

tux-10_thumb2_thumb

tux-11_thumb1_thumb

tux-12_thumb1_thumb

tux-13_thumb1_thumb

  • Go to Windows –> Services

tux-14_thumb1_thumb

  • Instead of Administrator use the User account name which you created in the first few steps of Oracle Tuxedo Installation.

tux-15_thumb2_thumb

  • This concludes the installation and configuration of Oracle Tuxedo.

Next steps continued in Part 2.

Thanks,

Vishal Modi

Categories: Blogs

Test Blog from Windows Live Writer.

BizTalkUnleashed Blog - Tue, 2012-01-24 19:25

Tada!!!

-Vishal Mody

Categories: Blogs