KEEP IN TOUCH CALL US: 877 513 3118
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:
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.
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.
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:
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).
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.
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!
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,
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.
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:
Success:
Failure:
Hope these helps.
Thanks,
Vishal Mody
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 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); }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 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 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.
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.
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).ClaimsThat’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!
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!).

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.
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:

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.

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:

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

Another interesting thing in the manual is this:

Which in my humble opinion summarizes a lot of years in the history of mechanical engineering.
With the capsules you can assemble these things:






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.
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.
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.

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.
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:

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.

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:

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

Otra perla del manual es este gráfico:

Que en mi opinión sintetiza muchisimos años de la historia de la mecánica.
Con las partes antes mencionadas se puede armar este tipo de cosas:






El manual de instrucciones trae muchos ejemplos más pero no es mi intención aburrir.
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.
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.
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.
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
More detailed information on PeopleSoft Adapter Architecture can be found on MSDN.
Requirements for PeopleSoft Adapter:
Installing BizTalk Server Enterprise Adapters:
Configuring PeopleSoft Adapter for BizTalk Server:
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:
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.
Select PeopleTools, Security, Permissions & Roles, Permission Lists.
Click Search, select the relevant Permission List, and click the appropriate list hyperlink. The Permission List pane opens on the right.
Click the right arrow next to the Sign-on Times tab to display the Component Interfaces tab. Click the Component Interfaces tab.
Click the + button to add a new row to the Component Interfaces list.
Select the GET_CI_INFO component interface and click Edit.
Click Full Access (All) to set the methods to Full Access. Click OK.
Scroll down to the bottom of the Component Interfaces window and click Save.
Select PeopleTools, Security, Permissions & Roles, Roles. Click Search, select the relevant Role and click the appropriate list hyperlink.
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]
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
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.
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.
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.
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.
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. ![]()
In the next coming blog posts we will see how we can generate metadata with this GET_CI_INFO Component Interface.
Regards,
Vishal Mody ![]()
PS: Reference from MSDN article : Microsoft BizTalk Adapters for PeopleSoft
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”,
The “CustomerController” can have the following operations:
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 hereIf 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); });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:
Updating PeopleTools Database Objects
Altering PeopleTools Tables:
Updating the PeopleTools System Data:
This concludes post database configurations.
Step10: Configuring the Application Server on Windows:
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.
Step11: Setting up the PeopleSoft Pure Internet Architecture(PIA):
Starting the domain..................
The domain has started.
Step12: Accessing the PeopleSoft Application:
This concludes the installation and configuration of PeopleSoft HRMS 9.0 Application.
Step6: Installing People Tools 8.52:
Step 7: Installation PeopleSoft Application Software (HRMS 9.0):
Step8: Installing and configuring PeopleSoft Databases:
Next steps continued in Part 3.
Thanks,
Vishal Modi
Environment what we are building consists of:
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:
Step2: Download all software required from Oracle
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:
Step4: Installing Oracle WebLogic on Windows:
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
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.
Step5: Installing Oracle Tuxedo:
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.
Next steps continued in Part 2.
Thanks,
Vishal Modi