Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7018 Articles
article-image-terms-and-concepts-related-mdx
Packt
09 Aug 2011
8 min read
Save for later

Terms and Concepts Related to MDX

Packt
09 Aug 2011
8 min read
MDX with Microsoft SQL Server 2008 R2 Analysis Services Cookbook More than 80 recipes for enriching your Business Intelligence solutions with high-performance MDX calculations and flexible MDX queries in this book and eBook Parts of an MDX query This section contains the brief explanation of the basic elements of MDX queries: members, sets, tuples, axes, properties, and so on. Regular members Regular dimension members are members sourced from the underlying dimension tables. They are the building blocks of dimensions, fully supported in any type of drill operations, drillthrough, scopes, subqueries, and probably all SSAS front-ends. They can have children and be organized in multilevel user hierarchies. Some of the regular member's properties can be dynamically changed using scopes in MDX script or cell calculations in queries - color, format, font, and so on. Measures are a type of regular members, found on the Measures dimension/hierarchy. The other type of members is calculated members. Calculated members Calculated members are artificial members created in a query, session, or MDX script. They do not exist in the underlying dimension table and as such are not supported in drillthrough and scopes. In subqueries, they are only supported if the connection string includes one of these settings: Subqueries = 1 or Subqueries = 2. See here for examples: http://tinyurl.com/ChrisSubquerySettings They also have a limited set of properties compared to regular members and worse support than regular members in some SSAS front-ends. An often practiced workaround is creating dummy regular members in a dimension table and then using MDX script assignments to provide the calculation for them. They are referred to as "Dummy" because they never occur in the fact table which also explains the need for assignments. Tuples A tuple is a coordinate in the multidimensional cube. That coordinate can be huge and is often such. For example, a cube with 10 dimensions each having 5 attributes is a 51 dimensional object (measures being that extra one). To fully define a coordinate we would have to reference every single attribute in that cube. Fortunately, in order to simplify their usage, tuples are allowed to be written using a part of the full coordinate only. The rest of the coordinate inside the tuple is implicitly evaluated by SSAS engine, either using the current members (for unrelated hierarchies) or through the mechanism known as strong relationships (for related hierarchies). It's worth mentioning that the initial current members are cube's default members. Any subsequent current members are derived from the current context of the query or the calculation. Evaluation of implicit members can sometimes lead to unexpected problems. We can prevent those problems by explicitly specifying all the hierarchies we want to have control over and thereby not letting the implicit evaluation to occur for those hierarchies. Contrary to members and sets, tuples are not an object that can be defined in the WITH part of the query or in MDX script. They are non-persistent. Tuples can be found in sets, during iteration or in calculations. They are often used to set or overwrite the current context, in other words, to jump out of the current context and get the value in another coordinate of the cube. Another important aspect of tuples is their dimensionality. When building a set from tuples, two or more tuples can be combined only if they are built from the same hierarchies, specified in the exact same order. That's their dimensionality. You should know that rearranging the order of hierarchies in a tuple doesn't change its value. Therefore, this can be the first step we can do to make the tuples compatible. The other thing is adding the current members of hierarchies present only in the other tuple, to match the other tuple's dimensionality. Named sets A named set is a user-defined collection of members, more precisely, tuples. Named sets are found in queries, sessions, and MDX scripts. Query-based named sets are equivalent to dynamic sets in MDX script. They both react to the context of subquery and slicer. Contrary to them, static sets are constant, independent of any context. Only the sets that have the same dimensionality can be combined together because what we really combine are the tuples they are built from. It is possible to extract one or more hierarchies from the set. It is also possible to expand the set by crossjoining it with hierarchies not present in its tuples. These processes are known as reducing and increasing the dimensionality of a set. Set alias Set aliases can be defined in calculations only, as a part of that calculation and not in the WITH part of the query as a named set. This is done by identifying a part of the calculation that represents a set and giving a name to that expression inside the calculation, using the AS keyword. This way that set can be used in other parts of the calculation or even other calculations of the query or MDX script. Set aliases enable true dynamic evaluation of sets in a query because they can be evaluated for each cell if used inside a calculated measure. The positive effect is that they are cached, calculated only once and used many times in the calculation or query. The downside is that they prevent block-computation mode because the above mentioned evaluation is performed for each cell individually. In short, set aliases can be used in long calculations, where the same set appears multiple times or when that set needs to be truly dynamic. At the same time, they are to be avoided in iterations of any kind. Axis An axis is a part of the query where a set is projected at. A query can have up to 128 axes although most queries have 1 or 2 axes. A query with no axis is also a valid query but almost never used. The important thing to remember is that axes are evaluated independently. SSAS engine knows in which order to calculate them if there is a dependency between them. One way to create such a dependency is to refer to the current member of a hierarchy on the other axis. The other option would be to use the Axis() function. Some SSAS front-ends generate MDX queries that break the axes dependencies established through calculations. The workaround calculations can be very hard if not impossible. Slicer The slicer, also known as the filter axis or the WHERE clause, is a part of the query which sets the context for the evaluation of members and sets on axes and in the WITH part of the query. The slicer, which can be anything from a single tuple up to the multidimensional set, interacts with sets on axes. A single member of a hierarchy in slicer forces the coordinate and reduces the related sets on axes by removing all non-existing combinations. Multiple members of the same hierarchy are not that strong. In their case, individual members in sets on axes overwrite the context of the slicer during their evaluation. Finally, the context established by the slicer can be overwritten in the calculations using tuples. Subquery The subquery, also known as the subselect, is a part of the query which executes first and determines the cube space to be used in the query. Unlike slicer, the subquery doesn't set the coordinate for the query. In other words, current members of all hierarchies (related, unrelated, and even the same hierarchy used in the subquery) remain the same. What the subquery does is it applies the VisualTotals operation on members of hierarchies used in the subquery. The VisualTotals operation changes each member's value with the aggregation value of its children, but only those present in the subquery. Because the slicer and the subquery have different behaviors, one should not be used as a replacement for the other. Whenever you need to set the context for the whole query, use the slicer. That will adjust the total for all hierarchies in the cube. If you only need to adjust the total for some hierarchies in the cube and not for the others, subquery is the way to go; specify those hierarchies in the subquery. This is also an option if you need to prevent any attribute interaction between your subquery and the query. The areas where the subquery is particularly good at are grouping of non-granular attributes, advanced set logic, and restricting members on hierarchies. Cell properties Cell properties are properties that can be used to get specific behaviors for cells. For example: colors, font sizes, types and styles, and so on. Unless explicitly asked for, only the Cell_Ordinal, Value, and Formatted_Value properties are returned by an MDX query. Dimension properties Dimension properties are a set of member properties that return extra information about members on axes. Intrinsic member properties are Key, Name, and Value; the others are those defined by the user for a particular hierarchy in the Dimension Designer. In client tools, dimension properties are often shown in the grid next to the attribute they are bound to or in the hint over that attribute.  
Read more
  • 0
  • 0
  • 1700

article-image-autoscaling-windows-azure-service-management-rest-api
Packt
08 Aug 2011
9 min read
Save for later

Autoscaling with the Windows Azure Service Management REST API

Packt
08 Aug 2011
9 min read
  Microsoft Windows Azure Development Cookbook A hosted service may have a predictable pattern such as heavy use during the week and limited use at the weekend. Alternatively, it may have an unpredictable pattern identifiable through various performance characteristics. Windows Azure charges by the hour for each compute instance, so the appropriate number of instances should be deployed at all times. The basic idea is that the number of instances for the various roles in the hosted service is modified to a value appropriate to a schedule or to the performance characteristics of the hosted service. We use the Service Management API to retrieve the service configuration for the hosted service, modify the instance count as appropriate, and then upload the service configuration. In this recipe, we will learn how to use the Windows Azure Service Management REST API to autoscale a hosted service depending on the day of the week. Getting ready We need to create a hosted service. We must create an X.509 certificate and upload it to the Windows Azure Portal twice: once as a management certificate and once as a service certificate to the hosted service. How to do it... We are going to vary the instance count of a web role deployed to the hosted service by using the Windows Azure Service Management REST API to modify the instance count in the service configuration. We are going to use two instances of the web role from Monday through Friday and one instance on Saturday and Sunday, where all days are calculated in UTC. We do this as follows: Create a Windows Azure Project and add an ASP.Net Web Role to it. Add the following using statements to the top of WebRole.cs: using System.Threading; using System.Xml.Linq; using System.Security.Cryptography.X509Certificates; Add the following members to the WebRole class in WebRole.cs: XNamespace wa = "http://schemas.microsoft.com/windowsazure"; XNamespace sc = http://schemas.microsoft.com/ ServiceHosting/2008/10/ServiceConfiguration"; String changeConfigurationFormat = https://management.core. windows.net/{0}/services/hostedservices/{1}/deploymentslots/{2}/ ?comp=config"; String getConfigurationFormat = https://management.core.windows. net/{0}/services/hostedservices/{1}/deploymentslots/{2}"; String subscriptionId = RoleEnvironment.GetConfigurationSettingVal ue("SubscriptionId"); String serviceName = RoleEnvironment.GetConfigurationSettingValue ("ServiceName"); String deploymentSlot = RoleEnvironment.GetConfigurationSettingVal ue("DeploymentSlot"); String thumbprint = RoleEnvironment.GetConfigurationSettingValue ("Thumbprint"); String roleName = "WebRole1"; String instanceId = "WebRole1_IN_0"; Add the following method, implementing RoleEntryPoint.Run(), to the WebRole class: WebRole class: public override void Run() { Int32 countMinutes = 0; while (true) { Thread.Sleep(60000); if (++countMinutes == 20) { countMinutes = 0; if ( RoleEnvironment.CurrentRoleInstance.Id == instanceId) { ChangeInstanceCount(); } } } } Add the following method, controlling the instance count change, to the WebRole class: private void ChangeInstanceCount() { XElement configuration = LoadConfiguration(); Int32 requiredInstanceCount = CalculateRequiredInstanceCount(); if (GetInstanceCount(configuration) != requiredInstanceCount) { SetInstanceCount(configuration, requiredInstanceCount); String requestId = SaveConfiguration(configuration); } } Add the following method, calculating the required instance count, to the WebRole class: private Int32 CalculateRequiredInstanceCount() { Int32 instanceCount = 2; DayOfWeek dayOfWeek = DateTime.UtcNow.DayOfWeek; if (dayOfWeek == DayOfWeek.Saturday || dayOfWeek == DayOfWeek.Sunday) { instanceCount = 1; } return instanceCount; } Add the following method, retrieving the instance count from the service configuration, to the WebRole class: private Int32 GetInstanceCount(XElement configuration) { XElement instanceElement = (from s in configuration.Elements(sc + "Role") where s.Attribute("name").Value == roleName select s.Element(sc + "Instances")).First(); Int32 instanceCount = (Int32)Convert.ToInt32( instanceElement.Attribute("count").Value); return instanceCount; } Add the following method, setting the instance count in the service configuration, to the WebRole class: private void SetInstanceCount( XElement configuration, Int32 value) { XElement instanceElement = (from s in configuration.Elements(sc + "Role") where s.Attribute("name").Value == roleName select s.Element(sc + "Instances")).First(); instanceElement.SetAttributeValue("count", value); } Add the following method, creating the payload for the change deployment configuration operation, to the WebRole class: private XDocument CreatePayload(XElement configuration) { String configurationString = configuration.ToString(); String base64Configuration = ConvertToBase64String(configurationString); XElement xConfiguration = new XElement(wa + "Configuration", base64Configuration); XElement xChangeConfiguration = new XElement(wa + "ChangeConfiguration", xConfiguration); XDocument payload = new XDocument(); payload.Add(xChangeConfiguration); payload.Declaration = new XDeclaration("1.0", "UTF-8", "no"); return payload; } Add the following method, loading the service configuration, to the WebRole class: private XElement LoadConfiguration() { String uri = String.Format(getConfigurationFormat, subscriptionId, serviceName, deploymentSlot); ServiceManagementOperation operation = new ServiceManagementOperation(thumbprint); XDocument deployment = operation.Invoke(uri); String base64Configuration = deployment.Element( wa + "Deployment").Element(wa + "Configuration").Value; String stringConfiguration = ConvertFromBase64String(base64Configuration); XElement configuration = XElement.Parse(stringConfiguration); return configuration; } Add the following method, saving the service configuration, to the WebRole class: private String SaveConfiguration(XElement configuration) { String uri = String.Format(changeConfigurationFormat, subscriptionId, serviceName, deploymentSlot); XDocument payload = CreatePayload(configuration); ServiceManagementOperation operation = new ServiceManagementOperation(thumbprint); String requestId = operation.Invoke(uri, payload); return requestId; } Add the following utility methods, converting a String to and from its base-64 encoded version, to the WebRole class: private String ConvertToBase64String(String value) { Byte[] bytes = System.Text.Encoding.UTF8.GetBytes(value); String base64String = Convert.ToBase64String(bytes); return base64String; } private String ConvertFromBase64String(String base64Value) { Byte[] bytes = Convert.FromBase64String(base64Value); String value = System.Text.Encoding.UTF8.GetString(bytes); return value; } Add the ServiceManagementOperation class described in the Getting ready section of the Creating a Windows Azure hosted service recipe to the WebRole1 project. Set the ConfigurationSettings element in the ServiceDefinition.csdef file to: <ConfigurationSettings> <Setting name="DeploymentSlot" /> <Setting name="ServiceName" /> <Setting name="SubscriptionId" /> <Setting name="Thumbprint" /> </ConfigurationSettings> Set the ConfigurationSettings element in the ServiceDefinition.cscfg file to the following: <ConfigurationSettings> <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics. ConnectionString" alue="DefaultEndpointsProtocol=https;AccountNam e=ACCOUNT_NAME;AccountKey=ACCOUNT_KEY" /> <Setting name="DeploymentSlot" value="production" /> <Setting name="ServiceName" value="SERVICE_NAME" /> <Setting name="SubscriptionId" value="SUBSCRIPTION_ID" /> <Setting name="Thumbprint" value="THUMBPRINT" /> </ConfigurationSettings> How it works... In steps 1 and 2, we set up the WebRole class. In step 3, we add private members to define the XML namespace used in processing the response and the String format used in generating the endpoint for the change deployment configuration and get deployment operations. We then initialize several values from configuration settings in the service configuration file deployed to each instance. In step 4, we implement the Run() class . Every 20 minutes, the thread this method runs in wakes up and, only in the instance named WebRole1_IN_0, invokes the method controlling the instance count for the web role. This code runs in a single instance to ensure that there is no race condition with multiple instances trying to change the instance count simultaneously. In step 5, we load the service configuration. If we detect that the instance count should change we modify the service configuration to have the desired instance count and then save the service configuration. Note that the service configuration used here is downloaded and uploaded using the Service Management API. Step 6 contains the code where we calculate the needed instance count. In this example, we choose an instance count of 2 from Monday through Friday and 1 on Saturday and Sunday. All days are specified in UTC. This is the step where we should insert the desired scaling algorithm. In step 7, we retrieve the instance count for the web role from the service configuration. In step 8, we set the instance count to the desired value in the service configuration. In step 9, we create the payload for the change deployment configuration operation. We create a Configuration element and add a base-64 encoded copy of the service configuration to it. We add the Configuration element to the root ChangeConfiguration element which we then add to an XML document. In step 10, we use the ServiceManagementOperation utility class , described in the Creating a Windows Azure hosted service recipe, to invoke the get deployment operation on the Service Management API. The Invoke() method creates an HttpWebRequest, adds the required X.509 certificate, and sends the request to the get deployment endpoint. We load the response into an XML document from which we extract the base-64 encoded service configuration. We then convert this into its XML format and load this into an XElement which we return. In step 11, we use the ServiceManagementOperation utility class to invoke the change deployment configuration operation on the Service Management API. The Invoke() method creates an HttpWebRequest, adds the required X.509 certificate and the payload, and then sends the request to the change deployment configuration endpoint. It then parses the response to retrieve the request ID. In step 12, we add two utility methods to convert to and from a base-64 encoded String. In step 13, we add the ServiceManagementOperation utility class that we use to invoke operations against the Service Management API. In steps 14 and 15, we define some configuration settings in the service definition file and specify them in the service configuration file. We provide values for the Windows Azure Storage Service account name and access key. We also provide the subscription ID for the Windows Azure subscription, as well as the service name for current hosted service. We also need to add the thumbprint for the X.509 certificate we uploaded as a management certificate to the Windows Azure subscription and a service certificate to the hosted service we are deploying this application into. Note that this thumbprint is the same as that configured in the Certificate section of the ServiceConfiguration.cscfg file. This duplication is necessary because the Certificate section of this file is not accessible to the application code. Summary Windows Azure charges by the hour for each compute instance, so the appropriate number of instances should be deployed at all times. Autoscaling with the Windows Azure Service Management REST API as shown in this article is a boon in terms of keeping track of number of deployments at any time. Further resources on this subject: Managing Azure Hosted Services with the Service Management API [Article] Using the Windows Azure Platform PowerShell Cmdlets [Article] Windows Azure Diagnostics: Initializing the Configuration and Using a Configuration File [Article] Digging into Windows Azure Diagnostics [Article] Using IntelliTrace to Diagnose Problems with a Hosted Service [Article]
Read more
  • 0
  • 0
  • 3111

article-image-managing-azure-hosted-services-service-management-api
Packt
08 Aug 2011
11 min read
Save for later

Managing Azure Hosted Services with the Service Management API

Packt
08 Aug 2011
11 min read
  Microsoft Windows Azure Development Cookbook Over 80 advanced recipes for developing scalable services with the Windows Azure platform         Read more about this book       (For more resources on this subject, see here.) Introduction The Windows Azure Portal provides a convenient and easy-to-use way of managing the hosted services and storage account in a Windows Azure subscription, as well as any deployments into these hosted services. The Windows Azure Service Management REST API provides a programmatic way of managing the hosted services and storage accounts in a Windows Azure subscription, as well as any deployments into these hosted services. These techniques are complementary and, indeed, it is possible to use the Service Management API to develop an application that provides nearly all the features of the Windows Azure Portal. The Service Management API provides almost complete control over the hosted services and storage accounts contained in a Windows Azure subscription. All operations using this API must be authenticated using an X.509 management certificate. We see how to do this in the Authenticating against the Windows Azure Service Management REST API recipe in Controlling Access in the Windows Azure Platform. In Windows Azure, a hosted service is an administrative and security boundary for an application. A hosted service specifies a name for the application, as well as specifying a Windows Azure datacenter or affinity group into which the application is deployed. In the Creating a Windows Azure hosted service recipe, we see how to use the Service Management API to create a hosted service. A hosted service has no features or functions until an application is deployed into it. An application is deployed by specifying a deployment slot, either production or staging, and by providing the application package containing the code, as well as the service configuration file used to configure the application. We see how to do this using the Service Management API in the Deploying an application into a hosted service recipe. Once an application has been deployed, it probably has to be upgraded occasionally. This requires the provision of a new application package and service configuration file. We see how to do this using the Service Management API in the Upgrading an application deployed to a hosted service recipe. A hosted service has various properties defining it as do the applications deployed into it. There could, after all, be separate applications deployed into each of the production and staging slots. In the Retrieving the properties of a hosted service recipe, we see how to use the Service Management API to get these properties. An application deployed as a hosted service in Windows Azure can use the Service Management API to modify itself while running. Specifically, an application can autoscale by varying the number of role instances to match anticipated demand. We see how to do this in the Autoscaling with the Windows Azure Service Management REST API recipe. We can use the Service Management API to develop our own management applications. Alternatively, we can use one of the PowerShell cmdlets libraries that have already been developed using the API. Both the Windows Azure team and Cerebrata have developed such libraries. We see how to use them in the Using the Windows Azure Platform PowerShell Cmdlets recipe. Creating a Windows Azure hosted service A hosted service is the administrative and security boundary for an application deployed to Windows Azure. The hosted service specifies the service name, a label, and either the Windows Azure datacenter location or the affinity group into which the application is to be deployed. These cannot be changed once the hosted service is created. The service name is the subdomain under cloudapp.net used by the application, and the label is a humanreadable name used to identify the hosted service on the Windows Azure Portal. The Windows Azure Service Management REST API exposes a create hosted service operation. The REST endpoint for the create hosted service operation specifies the subscription ID under which the hosted service is to be created. The request requires a payload comprising an XML document containing the properties needed to define the hosted service, as well as various optional properties. The service name provided must be unique across all hosted services in Windows Azure, so there is a possibility that a valid create hosted service operation will fail with a 409 Conflict error if the provided service name is already in use. As the create hosted service operation is asynchronous, the response contains a request ID that can be passed into a get operation status operation to check the current status of the operation. In this recipe, we will learn how to use the Service Management API to create a Windows Azure hosted service. Getting ready The recipes in this article use the ServiceManagementOperation utility class to invoke operations against the Windows Azure Service Management REST API. We implement this class as follows: Add a class named ServiceManagementOperation to the project. Add the following assembly reference to the project: System.Xml.Linq.dll Add the following using statements to the top of the class file: using System.Security.Cryptography.X509Certificates;using System.Net;using System.Xml.Linq;using System.IO; Add the following private members to the class: String thumbprint;String versionId = "2011-02-25"; Add the following constructor to the class: public ServiceManagementOperation(String thumbprint){ this.thumbprint = thumbprint;} Add the following method, retrieving an X.509 certificate from the certificate store, to the class: private X509Certificate2 GetX509Certificate2( String thumbprint){ X509Certificate2 x509Certificate2 = null; X509Store store = new X509Store("My", StoreLocation.LocalMachine); try { store.Open(OpenFlags.ReadOnly); X509Certificate2Collection x509Certificate2Collection = store.Certificates.Find( X509FindType.FindByThumbprint, thumbprint, false); x509Certificate2 = x509Certificate2Collection[0]; } finally { store.Close(); } return x509Certificate2;} Add the following method, creating an HttpWebRequest, to the class: private HttpWebRequest CreateHttpWebRequest( Uri uri, String httpWebRequestMethod){ X509Certificate2 x509Certificate2 = GetX509Certificate2(thumbprint); HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(uri); httpWebRequest.Method = httpWebRequestMethod; httpWebRequest.Headers.Add("x-ms-version", versionId); httpWebRequest.ClientCertificates.Add(x509Certificate2); httpWebRequest.ContentType = "application/xml"; return httpWebRequest;} Add the following method, invoking a GET operation on the Service Management API, to the class: public XDocument Invoke(String uri){ XDocument responsePayload; Uri operationUri = new Uri(uri); HttpWebRequest httpWebRequest = CreateHttpWebRequest(operationUri, "GET"); using (HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse()) { Stream responseStream = response.GetResponseStream(); responsePayload = XDocument.Load(responseStream); } return responsePayload;} Add the following method, invoking a POST operation on the Service Management API, to the class: public String Invoke(String uri, XDocument payload){ Uri operationUri = new Uri(uri); HttpWebRequest httpWebRequest = CreateHttpWebRequest(operationUri, "POST"); using (Stream requestStream = httpWebRequest.GetRequestStream()) { using (StreamWriter streamWriter = new StreamWriter(requestStream, System.Text.UTF8Encoding.UTF8)) { payload.Save(streamWriter, SaveOptions.DisableFormatting); } } String requestId; using (HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse()) { requestId = response.Headers["x-ms-request-id"]; } return requestId;} How it works... In steps 1 through 3, we set up the class. In step 4, we add a version ID for service management operations. Note that Microsoft periodically releases new operations for which it provides a new version ID, which is usually applicable for operations added earlier. In step 4, we also add a private member for the X.509 certificate thumbprint that we initialize in the constructor we add in step 5. In step 6, we open the Personal (My) certificate store on the local machine level and retrieve an X.509 certificate identified by thumbprint. If necessary, we can specify the current user level, instead of the local machine level, by using StoreLocation.CurrentUser instead of StoreLocation.LocalMachine. In step 7, we create an HttpWebRequest with the desired HTTP method type, and add the X.509 certificate to it. We also add various headers including the required x-ms-version. In step 8, we invoke a GET request against the Service Management API and load the response into an XML document which we then return. In step 9, we write an XML document, containing the payload, into the request stream for an HttpWebRequest and then invoke a POST request against the Service Management API. We extract the request ID from the response and return it. How to do it... We are now going to construct the payload required for the create hosted service operation, and then use it when we invoke the operation against the Windows Azure Service Management REST API. We do this as follows: Add a new class named CreateHostedServiceExample to the WPF project. If necessary, add the following assembly reference to the project: System.Xml.Linq.dll Add the following using statement to the top of the class file: using System.Xml.Linq; Add the following private members to the class: XNamespace wa = "http://schemas.microsoft.com/windowsazure";String createHostedServiceFormat ="https://management.core.windows.net/{0}/services/hostedservices"; Add the following method, creating a base-64 encoded string, to the class: private String ConvertToBase64String(String value){ Byte[] bytes = System.Text.Encoding.UTF8.GetBytes(value); String base64String = Convert.ToBase64String(bytes); return base64String;} Add the following method, creating the payload, to the class: private XDocument CreatePayload( String serviceName, String label, String description, String location, String affinityGroup){ String base64LabelName = ConvertToBase64String(label); XElement xServiceName = new XElement(wa + "ServiceName", serviceName); XElement xLabel = new XElement(wa + "Label", base64LabelName); XElement xDescription = new XElement(wa + "Description", description); XElement xLocation = new XElement(wa + "Location", location); XElement xAffinityGroup = new XElement(wa + "AffinityGroup", affinityGroup); XElement createHostedService = new XElement(wa +"CreateHostedService"); createHostedService.Add(xServiceName); createHostedService.Add(xLabel); createHostedService.Add(xDescription); createHostedService.Add(xLocation); //createHostedService.Add(xAffinityGroup); XDocument payload = new XDocument(); payload.Add(createHostedService); payload.Declaration = new XDeclaration("1.0", "UTF-8", "no"); return payload;} Add the following method, invoking the create hosted service operation, to the class: private String CreateHostedService(String subscriptionId, String thumbprint, String serviceName, String label, String description, String location, String affinityGroup){ String uri = String.Format(createHostedServiceFormat, subscriptionId); XDocument payload = CreatePayload(serviceName, label, description, location, affinityGroup); ServiceManagementOperation operation = new ServiceManagementOperation(thumbprint); String requestId = operation.Invoke(uri, payload); return requestId;} Add the following method, invoking the methods added earlier, to the class: public static void UseCreateHostedServiceExample(){ String subscriptionId = "{SUBSCRIPTION_ID}"; String thumbprint = "{THUMBPRINT}"; String serviceName = "{SERVICE_NAME}"; String label = "{LABEL}"; String description = "Newly created service"; String location = "{LOCATION}"; String affinityGroup = "{AFFINITY_GROUP}"; CreateHostedServiceExample example = new CreateHostedServiceExample(); String requestId = example.CreateHostedService( subscriptionId, thumbprint, serviceName, label, description, location, affinityGroup);} How it works... In steps 1 through 3, we set up the class. In step 4, we add private members to define the XML namespace used in creating the payload and the String format used in generating the endpoint for the create hosted service operation. In step 5, we add a helper method to create a base-64 encoded copy of a String. We create the payload in step 6 by creating an XElement instance for each of the required and optional properties, as well as the root element. We add each of these elements to the root element and then add this to an XML document. Note that we do not add an AffinityGroup element because we provide a Location element and only one of them should be provided. In step 7, we use the ServiceManagementOperation utility class , described in the Getting ready section, to invoke the create hosted service operation on the Service Management API. The Invoke() method creates an HttpWebRequest, adds the required X.509 certificate and the payload, and then sends the request to the create hosted services endpoint. It then parses the response to retrieve the request ID which can be used to check the status of the asynchronous create hosted services operation. In step 8, we add a method that invokes the methods added earlier. We need to provide the subscription ID for the Windows Azure subscription, a globally unique service name for the hosted service, and a label used to identify the hosted service in the Windows Azure Portal. The location must be one of the official location names for a Windows Azure datacenter, such as North Central US. Alternatively, we can provide the GUID identifier of an existing affinity group and swap the commenting out in the code, adding the Location and AffinityGroup elements in step 6. We see how to retrieve the list of locations and affinity groups in the Locations and affinity groups section of this recipe. There's more... Each Windows Azure subscription can create six hosted services. This is a soft limit that can be raised by requesting a quota increase from Windows Azure Support at the following URL: http://www.microsoft.com/windowsazure/support/ There are also soft limits on the number of cores per subscription (20) and the number of Windows Azure storage accounts per subscription (5). These limits can also be increased by request to Windows Azure Support. Locations and affinity groups The list of locations and affinity groups can be retrieved using the list locations and list affinity groups operations respectively in the Service Management API. We see how to do this in the Using the Windows Azure Platform PowerShell Cmdlets recipe. As of this writing, the locations are: Anywhere US South Central US North Central US Anywhere Europe North Europe West Europe Anywhere Asia Southeast Asia East Asia The affinity groups are specific to a subscription.
Read more
  • 0
  • 0
  • 2837

article-image-android-30-application-development-multimedia-management
Packt
08 Aug 2011
6 min read
Save for later

Android 3.0 Application Development: Multimedia Management

Packt
08 Aug 2011
6 min read
Android 3.0 Application Development Cookbook Over 70 working recipes covering every aspect of Android development Very few successful applications are completely silent or have only static graphics, and in order that Android developers take full advantage of the advanced multimedia capabilities of today's smartphones, the system provides the android.media package, which contains many useful classes. The MediaPlayer class allows the playback of both audio and video from raw resources, files, and network streams, and the MediaRecorder class makes it possible to record both sound and images. Android also offers ways to manipulate sounds and create interactive effects through the use of the SoundPool class, which allows us to not only bend the pitch of our sounds but also to play more than one at a time.   Playing an audio file from within an application One of the first things that we may want to do with regards to multimedia is play back an audio file. Android provides the android.media.MediaPlayer class for us and this makes playback and most media related functions remarkably simple. In this recipe we will create a simple media player that will play a single audio file. Getting ready Before we start this project we will need an audio file for playback. Android can decode audio with any of the following file extensions: .3GP .MP4 .M4A .MP3 .OGG .WAV There are also quite a few MIDI file formats that are acceptable but have not been included here as their use is less common and their availability often depends on whether a device is running the standard Android platform or a specific vendor extension. Before you start this exercise create or find a short sound sample in one of the given formats. We used a five second Ogg Vorbis file and called it my_sound_file.ogg. How to do it... Start up a new Android project in Eclipse and create a new folder: res/raw. Place the sound file that you just prepared in this folder. In this example we refer to it as my_sound_file. Using either the Graphical Layout or the main.xml panel edit the file res/layout/main.xml to contain three buttons, as seen in the following screenshot: Call these buttons play_button, pause_button and stop_button. In the Java activity code declare a MediaPlayer in the onCreate() method: @Override public void onCreate(Bundle state) { super.onCreate(state); setContentView(R.layout.main); final MediaPlayer mPlayer; Associate the buttons we added in step 3 with Java variables by adding the following lines to onCreate(): Button playButton = (Button) findViewById(R.id.play_button); Button pauseButton = (Button) findViewById(R.id.pause_button); Button stopButton = (Button) findViewById(R.id.stop_button); We need a click listener for our play button. This also can be defined from within onCreate(): playButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { mPlayer = MediaPlayer.create(this, R.raw.my_sound_file); mPlayer.setLooping(true); mPlayer.start(); } }); Next add a listener for the pause button as follows: pauseButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { mPlayer.pause(); } }); Finally, include a listener for the stop button: stopButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { mPlayer.stop(); mPlayer.reset(); } }); Now run this code on an emulator or your handset and test each of the buttons. How it works... The MediaPlayer class provides some useful functions and the use of start(), pause(), stop(), and setLooping() should be clear. However, if you are thinking that calling MediaPlayer.create(context, ID) every time the start button is pressed is overkill, you would be correct. This is because once stop() has been called on the MediaPlayer, the media needs to be reset and prepared (with reset() and prepare()) before start() can be called again. Fortunately MediaPlayer.create() also calls prepare() so that the first time we play an audio file we do not have to worry about this. The lifecycle of the MediaPlayer is not always straightforward and the order in which it takes on various states is best explained diagrammatically: Otherwise, MediaPlayer has lots of useful methods such as isPlaying(), which will return a Boolean telling us whether our file is being played or not, or getDuration() and getCurrentPosition(), which inform us of how long the sample is and how far through it we are. There are also some useful hooks that we can employ using MediaPlayer and the most commonly used are onCompletionListener() and onErrorListener(). There's more... We are not restricted to playing back raw resources. We can also playback local files or even stream audio. Playing back a file or a stream Use the MediaPlayer.setDataSource(String) method to play an audio file or stream. In the case of streaming audio this will need to be a URL representing a media file that is capable of being played progressively, and you will need to prepare the media player each time it runs: MediaPlayer player = new MediaPlayer(); player.setDataSource("string value of your file path or URL"); player.prepare(); player.start(); It is essential to surround setDataSource() with a try/catch clause in case the source does not exist when dealing with removable or online media.   Playing back video from external memory The MediaPlayer class that we met in the previous recipe works for video in the same manner that it does for audio and so as not to make this task a near copy of the last, here we will look at how to play back video files stored on an SD card using the VideoView object. Getting ready This recipe requires a video file for our application to playback. Android can decode H.263, H.264 and MPEG-4 files; generally speaking this means files with .3gp and .mp4 file extensions. For platforms since 3.0 (API level 11) it is also possible to manage H.264 AVC files. Find a short video clip in one of these compatible formats and save it on the SD card of your handset. Alternatively you can create an emulator with an SD card enabled and push your video file onto it. This can be done easily through Eclipse's DDMS perspective from the File Explorer tab: In this example we called our video file my_video.3gp.  
Read more
  • 0
  • 0
  • 4295

article-image-using-windows-azure-platform-powershell-cmdlets
Packt
08 Aug 2011
4 min read
Save for later

Using the Windows Azure Platform PowerShell Cmdlets

Packt
08 Aug 2011
4 min read
  Microsoft Windows Azure Development Cookbook Over 80 advanced recipes for developing scalable services with the Windows Azure platform         Read more about this book       (For more resources on this subject, see here.) Getting ready If necessary, we can download PowerShell 2 from the Microsoft download center at the following URL: http://www.microsoft.com/download/en/details.aspx?id=11829 We need to download and install the Windows Azure Platform PowerShell cmdlets. The package with the cmdlets can be downloaded from the following URL: http://wappowershell.codeplex.com/ Once the package has been downloaded, the cmdlets need to be built and installed. The installed package contains a StartHere file explaining the process. How to do it... We are going to use the Windows Azure Platform cmdlets to retrieve various properties of a Windows Azure subscription and a hosted service in it. Create a PowerShell script named Get-Properties.ps1 and insert the following text: $subscriptionId = 'SUBSCRIPTION_ID' $serviceName = 'SERVICE_NAME' $thumbprint = 'THUMBPRINT' $getCertificate = Get-Item cert:LocalMachineMy$thumbprint Add-PSSnapin AzureManagementToolsSnapIn Get-HostedServices -SubscriptionId $subscriptionId -Certificate $getCertificate Get-AffinityGroups -SubscriptionId $subscriptionId -Certificate $getCertificate Get-HostedProperties -SubscriptionId $subscriptionId -Certificate $getCertificate -ServiceName $serviceName Launch PowerShell. Navigate to the directory containing Get-Properties.ps1. Invoke the cmdlets to retrieve the properties: .Get-Properties.ps1 How it works... In step 1, we create the PowerShell script to invoke the get hosted service properties, list affinity groups, and get hosted service properties operations in the Windows Azure Service Management REST API. We need to provide the subscription ID for the Windows Azure subscription, the name of the hosted service, and the thumbprint for a management certificate uploaded to the Windows Azure subscription. In the script, we retrieve the X.509 certificate from the Personal (My) certificate store on the local machine level. If necessary, we can specify the current user level, instead of the local machine level, by using CurrentUser in place of LocalMachine when we define $getCertificate. In steps 2 and 3, we set up PowerShell. In step 4, we invoke the script using a . syntax to demonstrate that we really want to invoke an unsigned script in the current directory. There's more... PowerShell supports an execution policy to restrict the PowerShell scripts that can be run on a system. If the current execution policy does not permit the Windows Azure Service Management cmdlets to run, then the execution policy can be changed to remote signed by invoking the following at the command prompt: C:UsersAdministrator>PowerShell -command "Set-ExecutionPolicy RemoteSigned" This sets the global PowerShell execution context. PowerShell 2 introduced a command-line switch allowing it to be set only for the current invocation: C:UsersAdministrator>PowerShell -ExecutionPolicy RemoteSigned Azure Management cmdlets Cerebrata has released a commercial set of Azure Management cmdlets that are more extensive than the Windows Azure Service Management cmdlets. The following PowerShell script retrieves the list of affinity groups for a Windows Azure subscription, including the GUID identifier not available on the Windows Azure Portal: $subscriptionId = 'SUBSCRIPTION_ID' $thumbprint = 'THUMBPRINT' $getCertificate = Get-ChildItem -path cert:LocalMachineMy$thumbprint Add-PSSnapin AzureManagementCmdletsSnapIn Get-AffinityGroup -SubscriptionId $subscriptionId -Certificate $getCertificate We need to provide the subscription ID for the Windows Azure subscription, and the thumbprint for a management certificate uploaded to the Windows Azure subscription. In the script, we retrieve the X.509 certificate from the Personal (My) certificate store on the local machine level. If necessary, we can specify the current user level, instead of the local machine lever, by using CurrentUser in place of LocalMachine when we define $getCertificate. We can use the following command to retrieve the list of Windows Azure locations: Get-AzureDataCenterLocation -SubscriptionId $subscriptionId -Certificate $getCertificate Summary In this article we saw how to use the Windows Azure Platform PowerShell cmdlets to invoke various service operations in the Windows Azure Service Management REST API. Further resources on this subject: Managing Azure Hosted Services with the Service Management API [Article] Autoscaling with the Windows Azure Service Management REST API [Article] Windows Azure Diagnostics: Initializing the Configuration and Using a Configuration File [Article] Digging into Windows Azure Diagnostics [Article] Using IntelliTrace to Diagnose Problems with a Hosted Service [Article]
Read more
  • 0
  • 0
  • 11705

article-image-jquery-ui-themes-states-cues-overlays-and-shadows
Packt
05 Aug 2011
7 min read
Save for later

jQuery UI Themes: States, Cues, Overlays and Shadows

Packt
05 Aug 2011
7 min read
jQuery UI Themes Beginner's Guide Create new themes for your JQuery site with this step-by-step guide States jQueryUi widgets are always in one state or another. These states also play a role in themes. A widget in one state should look different than widgets in another state. These different appearances are controlled by CSS style properties within the theme. States are especially prevalent in widgets that interact with mouse events. When a user hovers over a widget that is interested in these types of events, the widget changes into a hover state. When the mouse leaves the widget, it returns to a default state. Even when nothing is happening with a widget—no events are taking place that the widget is interested in—the widget is in a default state. The reason we need a default state for widgets is so that they can return to their default appearance. The appearance of these states is entirely controlled through the applied theme. In this section, we'll change the ThemeRoller settings for widget states. Time for action - setting default state styles Some widgets that interact with the mouse have a default state applied to them. We can adjust how this state changes the appearance of the widget using ThemeRoller settings: Continuing with our theme design, expand the Clickable: default state section. In the Background color & texture section, click on the texture selector in the middle. Select the inset hard texture. In the Background color & texture section, set the background opacity to 65%. Change the Border color setting value to #b0b0b0. Change the Icon color setting value to #555555: What just happened? We've just changed the look and feel of the default widget state. We changed the background texture to match that of the header theme settings. Likewise, we also changed the background opacity to 65%, also to match the header theme settings. The border color is now slightly darker - this looks better with the new default state background settings. Finally, the icon color was updated to match the default state font color. Here is what the sample button looked like before we made our changes: Here is what the sample button looks like after we've updated our theme settings: Time for action - setting hover state styles The same widgets that may be in a default state, for instance, a button, may also be in a hover state. Widgets enter a hover state when a user moves the mouse pointer over the widget. We want our user interface to give some kind of visual indication that the user has hovered over something they can click. It's time to give our theme some hover state styles: Continuing with our theme design, expand the Clickable: hover state section. In the Background color & texture section, click on the texture selector in the middle. Select the inset hard texture. Change the Border color setting value to #787878. Change the Icon color setting value to #212121: What just happened? When we hover over widgets that support the hover state, their appearance is now harmonized with our theme settings. The background texture was updated to match the texture of the default state styles. The border color is now slightly darker. This makes the widget really stand out when the user hovers over it. At the same, it isn't so dark that it conflicts with the rest of the theme settings. Finally, we updated the icon color to match that of the font color. Here is what the sample button widget looked like before we change the hover state settings: Here is what the sample button widget looked like after we updated the hover state theme settings: Time for action - setting active state styles Some jQuery UI widgets, the same widgets that can be in either a default or hover state, can also be in an active state. Widgets become active after a user clicks them. For instance, the currently selected tab in a tabs widget is in an active state. We can control the appearance of active widgets through the ThemeRoller: Continuing with our theme design, expand the Clickable: active state section. In the Background color & texture section, change the color setting value on the left to #f9f9f9. In the Background color & texture section, click the texture selector in the middle. Select the flat texture. In the Background color & texture section, set the opacity setting value on the right-hand side to 100%. Change the Border color setting value to #808080. Change the Icon color setting value to #212121: What just happened? Widgets in the active state will now use our updated theme styles. We've changed the background color to something only marginally darker. The reason being, we are using the highlight soft texture in our content theme settings. This means that the color gets lighter toward the top. The color at the top is what we're aiming for in the active state styles. The texture has been changed to flat. Flat textures, unlike the others, have no pattern - they're simply a color. Accordingly, we've changed the background opacity to 100%. We do this because for these theme settings, we're only interested in showing the color. The active state border is slightly darker, a visual cue to show that the widget is in fact active. Finally, like other adjustments we've made in our theme, the icon color now mirrors the text color. Here is what the sample tabs widget looked like before we changed the active state theme settings: Here is what the sample tabs widget looks like after we've updated the active state theme settings. Notice that the selected tab's border stands out among the other tabs and how the selected tab blends better with the tab content. Cues In any web application, it is important to have the ability to notify users of events that have taken place. Perhaps an order was successfully processed, or a registration field was entered incorrectly. Both occurrences are worth letting the user know about. These are types of cues. The jQuery UI theming framework defines two types of cues used to notify the user. These are highlights and errors. A highlight cue is informational, something that needs to be brought to the user's attention. An error is something exceptional that should not have happened. Both cue categories can be customized to meet the requirements of any theme. It is important to keep in mind that cues are meant to aggressively grab the attention of the user - not to passively display information. So the theme styles applied to these elements really stand out. In this section we'll take a look at how to make this happen with the ThemeRoller. Time for action - changing the highlight cue A user of your jQuery UI application has just saved something. How do they know it was successful? Your application needs to inform them somehow—it needs to highlight the fact that something interesting just happened. To do this, your application will display a highlight cue. Let's add some highlight styles to our theme: Continuing with our theme design, expand the Highlight section. In the Background color & texture section, change the color setting value to #faf2c7. In the Background color & texture section, change the opacity setting value to 85%. Change the Border color setting value to #f8df49. Change the Text color setting value to #212121: What just happened? The theme settings for any highlight cues we display for the user have been updated. The background color is a shade darker and the opacity has been increased by 10%. The border color is now significantly darker than the background color. The contrast between the background and border colors defined here are now better aligned with the background-border contrast defined in other theme sections. Finally, we've updated the text color to be the same as the text in other sections. This is not for a noticeable difference (there isn't any), but for consistency reasons. Here is what the sample highlight cue looked like before we updated the theme settings: Here is what the sample highlight widget looks like after the theme setting changes:
Read more
  • 0
  • 0
  • 2825
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-how-perform-iteration-sets-mdx
Packt
05 Aug 2011
5 min read
Save for later

How to Perform Iteration on Sets in MDX

Packt
05 Aug 2011
5 min read
  MDX with Microsoft SQL Server 2008 R2 Analysis Services Cookbook More than 80 recipes for enriching your Business Intelligence solutions with high-performance MDX calculations and flexible MDX queries in this book and eBook Iteration is a very natural way of thinking for us humans. We set a starting point, we step into a loop, and we end when a condition is met. While we're looping, we can do whatever we want: check, take, leave, and modify items in that set. Being able to break down the problems in steps makes us feel that we have things under control. However, by breaking down the problem, the query performance often breaks down as well. Therefore, we have to be extra careful with iterations when data is concerned. If there's a way to manipulate the collection of members as one item, one set, without cutting that set into small pieces and iterating on individual members, we should use it. It's not always easy to find that way, but we should at least try. Iterating on a set in order to reduce it Getting ready Start a new query in SSMS and check that you're working on the right database. Then write the following query: SELECT { [Measures].[Customer Count], [Measures].[Growth in Customer Base] } ON 0, NON EMPTY { [Date].[Fiscal].[Month].MEMBERS } ON 1 FROM [Adventure Works] WHERE ( [Product].[Product Categories].[Subcategory].&[1] ) The query returns fiscal months on rows and two measures: a count of customers and their growth compared to the previous month. Mountain bikes are in slicer. Now let's see how we can get the number of days the growth was positive for each period. How to do it... Follow these steps to reduce the initial set: Create a new calculated measure in the query and name it Positive growth days. Specify that you need descendants of current member on leaves. Wrap around the FILTER() function and specify the condition which says that the growth measure should be greater than zero. Apply the COUNT() function on a complete expression to get count of days. The new calculated member's definition should look as follows, verify that it does. WITH MEMBER [Measures].[Positive growth days] AS FILTER( DESCENDANTS([Date].[Fiscal].CurrentMember, , leaves), [Measures].[Growth in Customer Base] > 0 ).COUNT Add the measure on columns. Run the query and observe if the results match the following image: How it works... The task says we need to count days for each time period and use only positive ones. Therefore, it might seem appropriate to perform iteration, which, in this case, can be performed using the FILTER() function. But, there's a potential problem. We cannot expect to have days on rows, so we must use the DESCENDANTS() function to get all dates in the current context. Finally, in order to get the number of items that came up upon filtering, we use the COUNT function. There's more... Filter function is an iterative function which doesn't run in block mode, hence it will slow down the query. In the introduction, we said that it's always wise to search for an alternative if available. Let's see if something can be done here. A keen eye will notice a "count of filtered items" pattern in this expression. That pattern suggests the use of a set-based approach in the form of SUM-IF combination. The trick is to provide 1 for the True part of the condition taken from the FILTER() statement and null for the False part. The sum of one will be equivalent to the count of filtered items. In other words, once rewritten, that same calculated member would look like this: MEMBER [Measures].[Positive growth days] AS SUM( Descendants([Date].[Fiscal].CurrentMember, , leaves), IIF( [Measures].[Growth in Customer Base] > 0, 1, null) ) Execute the query using the new definition. Both the SUM() and the IIF() functions are optimized to run in the block mode, especially when one of the branches in IIF() is null. In this particular example, the impact on performance was not noticeable because the set of rows was relatively small. Applying this technique on large sets will result in drastic performance improvement as compared to the FILTER-COUNT approach. Be sure to remember that in future. More information about this type of optimization can be found in Mosha Pasumansky's blog: http://tinyurl.com/SumIIF Hints for query improvements There are several ways you can avoid the FILTER() function in order to improve performance. When you need to filter by non-numeric values (i.e. properties or other metadata), you should consider creating an attribute hierarchy for often-searched items and then do one of the following: Use a tuple when you need to get a value sliced by that new member Use the EXCEPT() function when you need to negate that member on its own hierarchy (NOT or <>) Use the EXISTS() function when you need to limit other hierarchies of the same dimension by that member Use the NONEMPTY() function when you need to operate on other dimensions, that is, subcubes created with that new member Use the 3-argument EXISTS() function instead of the NONEMPTY() function if you also want to get combinations with nulls in the corresponding measure group (nulls are available only when the NullProcessing property for a measure is set to Preserve) When you need to filter by values and then count a member in that set, you should consider aggregate functions like SUM() with IIF() part in its expression, as described earlier.  
Read more
  • 0
  • 0
  • 7814

article-image-performing-common-mdx-related-tasks
Packt
05 Aug 2011
6 min read
Save for later

Performing Common MDX-related Tasks

Packt
05 Aug 2011
6 min read
  MDX with Microsoft SQL Server 2008 R2 Analysis Services Cookbook More than 80 recipes for enriching your Business Intelligence solutions with high-performance MDX calculations and flexible MDX queries in this book and eBook Skipping axis There are situations when we want to display just a list of members and no data associated with them. Naturally, we expect to get that list on rows, so that we can scroll through them nicely. However, the rules of MDX say we can't skip axes. If we want something on rows (which is AXIS(1) by the way), we must use all previous axes as well (columns in this case, which is also known as AXIS(0)). The reason why we want the list to appear on axis 1 and not axis 0 is because a horizontal list is not as easy to read as a vertical one. Is there a way to display those members on rows and have nothing on columns? Sure! This recipe shows how. Getting ready Follow these steps to set up the environment for this recipe: Start SQL Server Management Studio (SSMS) or any other application you use for writing and executing MDX queries and connect to your SQL Server Analysis Services (SSAS) 2008 R2 instance (localhost or servernameinstancename). Click on the New Query button and check that the target database is Adventure Works DW 2008R2. How to do it... Follow these steps to get a one-dimensional query result with members on rows: Put an empty set on columns (AXIS(0)). Notation for empty set is this: {}. Put some hierarchy on rows (AXIS(1)). In this case we used the largest hierarchy available in this cube – Customer hierarchy of the same dimension. Run the following query: SELECT { } ON 0, { [Customer].[Customer].[Customer].MEMBERS } ON 1 FROM [Adventure Works] How it works... Although we can't skip axes, we are allowed to provide an empty set on them. This trick allows us to get what we need – nothing on columns and a set of members on rows. There's more… Notice that this type of query is very convenient for parameter selection of another query as well as for search. See how it can be modified to include only those customers whose name contains the phrase "John": SELECT { } ON 0, { Filter( [Customer].[Customer].[Customer].MEMBERS, InStr( [Customer].[Customer].CurrentMember.Name, 'John' ) > 0 ) } ON 1 FROM [Adventure Works] In the final result, you will notice the "John" phrase in various positions in member names: The idea behind If you put a cube measure or a calculated measure with a non-constant expression on axis 0 instead, you'll slow down the query. Sometimes it won't be so obvious, sometimes it will. It will depend on the measure's definition and the number of members in the hierarchy being displayed. For example, if you put the Sales Amount measure on columns, that measure will have to be evaluated for each member in the rows. Do we need those values? No, we don't. The only thing we need is a list of members; hence we've used an empty set. That way, the SSAS engine doesn't have to go into cube space. It can reside in dimension space which is much smaller and the query is therefore more efficient. Possible workarounds In case of a third-party application or a control which has problems with this kind of MDX statement (i.e. expects something on columns and is not working with an empty set), we can define a constant measure (a measure returning null, 0, 1 or any other constant) and place it on columns instead of that empty set. For example, we can define a calculated measure in the MDX script whose definition is 1, or any other constant value, and use that measure on the columns axis. It might not be as efficient as an empty set, but it is a much better solution than the one with a regular (non-constant) cube measure like the Sales Amount measure.   Handling division by zero errors Another common task is handling errors, especially division by zero type of errors. This recipe offers a way to solve that problem. Not all versions of Adventure Works database have the same date range. If you're not using the recommended version of it, the one for the SSAS 2008 R2, you might have problems with queries. Older versions of Adventure Works database have dates up to the year 2006 or even 2004. If that's the case, make sure you adjust examples by offsetting years in the query with a fixed number. For example, the year 2006 should become 2002 and so on. Getting ready Start a new query in SQL Server Management Studio and check that you're working on Adventure Works database. Then write and execute this query: WITH MEMBER [Date].[Calendar Year].[CY 2006 vs 2005 Bad] AS [Date].[Calendar Year].[Calendar Year].&[2006] / [Date].[Calendar Year].[Calendar Year].&[2005], FORMAT_STRING = 'Percent' SELECT { [Date].[Calendar Year].[Calendar Year].&[2005], [Date].[Calendar Year].[Calendar Year].&[2006], [Date].[Calendar Year].[CY 2006 vs 2005 Bad] } * [Measures].[Reseller Sales Amount] ON 0, { [Sales Territory].[Sales Territory].[Country].MEMBERS } ON 1 FROM [Adventure Works] This query returns 6 rows with countries and 3 rows with years, the third row being the ratio of the previous two, as its definition says. The problem is that we get 1.#INFM on some cells. To be precise, that value (the formatted value of infinity), appears on rows where the CY 2005 is null. Here's a solution for that. How to do it... Follow these steps to handle division by zero errors: Copy the calculated member and paste it as another calculated member. During that, replace the term Bad with Good in its name, just to differentiate those two members. Copy the denominator. Wrap the expression in an outer IIF() statement. Paste the denominator in the condition part of the IIF() statement and compare it against 0. Provide null value for the True part. Your initial expression should be in the False part. Don't forget to include the new member on columns and execute the query: MEMBER [Date].[Calendar Year].[CY 2006 vs 2005 Good] AS IIF ([Date].[Calendar Year].[Calendar Year].&[2005] = 0, null, [Date].[Calendar Year].[Calendar Year].&[2006] / [Date].[Calendar Year].[Calendar Year].&[2005] ), FORMAT_STRING = 'Percent' The result shows that the new calculated measure corrects the problem – we don't get errors (the rightmost column, compared to the one on its left): How it works... A division by zero error occurs when the denominator is null or zero and the numerator is not null. In order to prevent this error, we must test the denominator before the division and handle the case when it is null or zero. That is done using an outer IIF() statement. It is enough to test just for zero because null = 0 returns True. There's more... SQLCAT's SQL Server 2008 Analysis Services Performance Guide has lots of interesting details regarding the IIF() function: http://tinyurl.com/PerfGuide2008 Additionally, you may find Jeffrey Wang's blog article useful in explaining the details of the IIF() function: http://tinyurl.com/IIFJeffrey Earlier versions of SSAS If you're using a version of SSAS prior to 2008 (that is, 2005), the performance will not be as good. See Mosha Pasumansky's article for more info: http://tinyurl.com/IIFMosha  
Read more
  • 0
  • 0
  • 2149

article-image-jquery-ui-themes-using-themeroller
Packt
04 Aug 2011
8 min read
Save for later

jQuery UI Themes: Using the ThemeRoller

Packt
04 Aug 2011
8 min read
jQuery UI Themes Beginner's Guide Create new themes for your JQuery site with this step-by-step guide ThemeRoller basics Before we start using the ThemeRoller application to design and build our own themes, we'll take a quick look at what makes it such a handy tool. There is a lot more to the ThemeRoller than simply changing themes—we also use it to build them. You can think of it as an IDE for jQuery UI themes. Instant feedback What makes the ThemeRoller application such a powerful development tool is the speed with which you get feedback to changes made in the theme design. Any change made in the ThemeRoller is instantaneously reflected in the sample widgets provided on the page. For instance, if I were to change a font setting, that change would be reflected immediately in the sample widgets provided on the same page. There is no need to update the application you're building to see the results of small adjustments made to theme style settings. The same is true of prepackaged themes in the ThemeRoller gallery. Selecting a theme will apply it to the same widgets - you get immediate feedback. This is very helpful in deciding on prepackaged themes. If you can see how it looks with jQuery UI widgets right away, that may dissuade you from using the theme or it may close the deal. The idea behind this feedback mechanism offered by the ThemeRoller is a sped-up development cycle. Eliminating several steps when developing anything, themes included, is a welcome feature. The dev tool The ThemeRoller dev tool is a simple bookmarket for Firefox that brings the entire ThemeRoller application into any page with jQuery UI widgets. The benefit of the dev tool is that it allows you to see immediate theme changes in the context of the application you're building. If you use the ThemeRoller application from the jQuery UI website, you can only see changes as they apply to the sample widgets provided. This can give you a better idea of what the theme changes will look like on a finished product. There are some limitations to using the dev tool though. If you're developing your application locally, not on a development server, you can't use the dev tool due to security restrictions. The dev tool is better suited for viewing changes to themes, or viewing different themes entirely, on a deployed user interface. Having said that, if you're designing a user interface with several collaborators, you might have a remote development server. In this scenario, the dev tool suits its name. Portability The ThemeRoller application is portable in more ways than one. The dev tool for Firefox allows us to use the application within any jQuery UI application. This means that we can design and tweak our jQuery UI themes as we build the widgets. This portability between applications means that we can build a single theme that works for a suite of applications, or a product line, if we're so inclined. We can also use the ThemeRoller application directly from the jQueryUI website. This is handy if we don't have any widgets built or if you're trying jQuery UI out for the first time and just want to browse the wide selection of prepackaged themes. Whatever approach you take, the application is the same and will always be consistent, as it is a hosted application. You don't need to concern yourself with installing an IDE for theme authors to collaborate with. The ThemeRoller application is available wherever they are. ThemeRoller gallery It is nice to have a wide variety of prepackaged themes to choose from. It isn't all that helpful if you can't see how they look. The ThemeRoller application has a gallery where we can not only browse prepackaged themes but also take them for a test drive. This section is about using the ThemeRoller gallery to view themes and get a feel of the variety available to us. Viewing themes The ThemeRoller application doesn't hide anything about the prepackaged themes in the gallery. When we preview a theme, we get to see how it looks when applied to widgets. The theme gallery even gives us a thumbnail in the browser to show a bird's eye view of the theme. So if you see a lot of black and you're looking for something bright, you don't need to bother selecting it to see how the widgets look with it. Time for action - previewing a theme It's time for us to preview a jQuery UI theme before we actually download it. We can get an idea of what a theme in the ThemeRoller gallery will look like when applied to widgets: Point your web browser to http://jqueryui.com/themeroller/. Select the Gallery tab in the ThemeRoller section on the right-hand side. Move your mouse pointer over any theme in the gallery. A visual indicator will be displayed. Select the theme thumbnail:   What just happened? We've just selected a theme to preview from the ThemeRoller gallery. You'll notice that all the sample widgets to the right are instantly updated with the new theme. If we wanted to, we could change our theme selection and the sample widgets are once again updated with the theme changes. You'll notice that once you make a theme selection, the URL in your address bar is now long and ugly. These are the individual theme settings for the chosen theme being passed to the ThemeRoller page with the sample widgets. You'll also notice that the theme selection on the left-hand side of the page isn't preserved. This is because we're passing individual theme settings and not the name of the theme itself, for example, instancetheme=darkness. We'll see why this distinction is important in a little bit. Downloading themes Once you've selected a theme from the gallery and you're happy with how it looks, it is time to download it and use it with your jQuery UI project. Downloading a theme is easy—each prepackaged theme has a download button that will take you to the jQuery UI download page. If we wanted to, we could download all themes in a single package to experiment with, locally. This would also eliminate the need for the ThemeRoller application, which you probably don't want to do. Time for action - downloading a theme The gallery is a nice way to preview a theme, but now we want to use it in our application. To do this, we need to download it. This is similar to downloading the jQuery UI toolkit: Point your web browser to http://jqueryui.com/themeroller/. Select the Gallery tab in the ThemeRoller section on the left-hand side. Find a theme you wish to download. Click on the Download button underneath the theme thumbnail. This will bring you to the jQuery UI download page. Notice that your chosen theme is selected on the right-hand side of the page. Click on the Download button to download your theme: What just happened? We've just selected a prepackaged theme from the ThemeRoller gallery and downloaded it. In fact, you just downloaded jQuery UI again. The difference being, the downloaded ZIP archive contains the theme you selected from the gallery. The same principles apply for extracting the archive and using your theme with your jQuery UI application. The downside is that if you're downloading a theme, chances are you already have a jQuery UI application under development. In this case, downloading jQuery UI JavaScript files is redundant. However, there is no easy way around this. This is one of the drawbacks to having a useful tool available to us—a minor drawback at that. If you're only interested in the theme, you simply need to extract the theme folder from the ZIP archive and copy it to your jQuery UI application directory. You then need to update your path in your HTML in including the appropriate CSS file. You'll also notice that after clicking on the Download button from the theme gallery, you're brought to the download page with an ugly URL. That is, you'll see something like /download/?themeParams=%3FffDefault instead of just /download. This is a requirement of the ThemeRoller application that allows developers to edit existing themes or to roll their own. Without these parameters, we wouldn't be able to download themes we have made changes to. The jQuery UI download page also includes an Advanced Settings section that is hidden by default. This is because you rarely need to use it. It allows you to set the CSS scope for your theme, useful if you're using multiple themes in a single user interface. This isn't a recommended practice; the key idea behind jQuery UI themes is consistency. The advanced settings also lets you change the name of the downloaded theme folder. This can be useful if you plan on changing your theme later, but you can always rename the folder after downloading it.
Read more
  • 0
  • 0
  • 3440

article-image-getting-started-netbeans
Packt
04 Aug 2011
6 min read
Save for later

Getting Started with NetBeans

Packt
04 Aug 2011
6 min read
Java EE 6 Development with NetBeans 7 Develop professional enterprise Java EE applications quickly and easily with this popular IDE In addition to being an IDE, NetBeans is also a platform. Developers can use NetBeans' APIs to create both NetBeans plugins and standalone applications. For a brief history of Netbeans, see http://netbeans.org/about/history.html. Although the NetBeans IDE supports several programming languages, because of its roots as a Java only IDE it is a lot more popular with this language. As a Java IDE, NetBeans has built-in support for Java SE (Standard Edition) applications, which typically run in the user's desktop or notebook computer; Java ME (Micro Edition), which typically runs in small devices such as cell phones or PDAs; and for Java EE (Enterprise Edition) applications, which typically run on "big iron" servers and can support thousands of concurrent users.   Obtaining NetBeans NetBeans can be obtained by downloading it from http://www.netbeans.org. To download NetBeans, we need to click on the button labeled Download Free NetBeans IDE 7.0 (the exact name of the button may vary depending on the current version of NetBeans). Clicking on this button will take us to a page displaying all of NetBeans download bundles. NetBeans download includes different NetBeans bundles that provide different levels of functionality. The following table summarizes the different available NetBeans bundles and describes the functionality they provide: NetBeans bundleDescriptionJava SEAllows development of Java desktop applications.Java EEAllows development of Java Standard Edition (typically desktop applications), and Java Enterprise Edition (enterprise application running on "big iron" servers) applications.C/C++Allows development of applications written in the C or C++ languages.PHPAllows development of web applications using the popular open source PHP programming language.AllIncludes functionality of all NetBeans bundles. To follow the examples, either the Java EE or the All bundle is needed. The screenshots were taken with the Java EE bundle. NetBeans may look slightly different if the All Pack is used, particularly, some additional menu items may be seen. The following platforms are officially supported: Windows 7/Vista/XP/2000 Linux x86 Linux x64 Solaris x86 Solaris x64 Mac OS X Additionally, NetBeans can be executed in any platform containing Java 6 or newer. To download a version of NetBeans to be executed in one of these platforms, an OS independent version of NetBeans is available for download. Although the OS independent version of NetBeans can be executed in all of the supported platforms, it is recommended to obtain the platform-specific version of NetBeans for your platform. The NetBeans download page should detect the operating system being used to access it, and the appropriate platform should be selected by default. If this is not the case, or if you are downloading NetBeans with the intention of installing it in another workstation on another platform, the correct platform can be selected from the drop down labeled, appropriately enough, Platform. Once the correct platform has been selected, we need to click on the appropriate Download button for the NetBeans bundle we wish to install. For Java EE development, we need either the Java EE or the All bundle. NetBeans will then be downloaded to a directory of our choice. Java EE applications need to be deployed to an application server. Several application servers exist in the market, both the Java EE and the All NetBeans bundles come with GlassFish and Tomcat bundled. Tomcat is a popular open source servlet container, it can be used to deploy applications using the Servlets, JSP and JSF, however it does not support other Java EE technologies such as EJBs or JPA. GlassFish is a 100 percent Java EE-compliant application server. We will be using the bundled GlassFish application server to deploy and execute our examples.   Installing NetBeans NetBeans requires a Java Development Kit (JDK) version 6.0 or newer to be available before it can be installed. NetBeans installation varies slightly between the supported platforms. In the following few sections we explain how to install NetBeans on each supported platform. Microsoft Windows For Microsoft Windows platforms, NetBeans is downloaded as an executable file named something like netbeans-7.0-ml-java-windows.exe, (exact name depends on the version of NetBeans and the NetBeans bundle that was selected for download). To install NetBeans on Windows platforms, simply navigate to the folder where NetBeans was downloaded and double-click on the executable file. Mac OS X For Mac OS X, the downloaded file is called something like netbeans-7.0-ml-javamacosx.dmg (exact name depends on the NetBeans version and the NetBeans bundle that was selected for download). In order to install NetBeans, navigate to the location where the file was downloaded and double-click on it. The Mac OS X installer contains four packages, NetBeans, GlassFish, Tomcat, and OpenESB, these four packages need to be installed individually, They can be installed by simply double-clicking on each one of them. Please note that GlassFish must be installed before OpenESB. Linux and Solaris For Linux and Solaris, NetBeans is downloaded in the form of a shell script. The name of the file will be similar to netbeans-7.0-ml-java-linux.sh, netbeans-7.0-mljava-solaris-x86.sh, or netbeans-7.0-ml-java-solaris-sparc.sh, depending on the version of NetBeans, the selected platform and the selected NetBeans bundle. Before NetBeans can be installed in these platforms, the downloaded file needs to be made executable. This can be done in the command line by navigating to the directory where the NetBeans installer was downloaded and executing the following command: chmod +x ./filename.sh Substitute filename.sh with the appropriate file name for the platform and the NetBeans bundle. Once the file is executable it can be installed from the command line: ./filename.sh Again substitute filename.sh with the appropriate file name for the platform and the NetBeans bundle. Other platforms For other platforms, NetBeans can be downloaded as a platform-independent zip file. The name of the zip file will be something like netbeans-7.0-201007282301-mljava.zip (exact file name may vary, depending on the exact version of NetBeans downloaded and the NetBeans bundle that was selected). To install NetBeans on one of these platforms, simply extract the zip file to any suitable directory.  
Read more
  • 0
  • 0
  • 2850
article-image-opengl-40-building-c-shader-program-class
Packt
03 Aug 2011
5 min read
Save for later

OpenGL 4.0: Building a C++ Shader Program Class

Packt
03 Aug 2011
5 min read
  OpenGL 4.0 Shading Language Cookbook Over 60 highly focused, practical recipes to maximize your OpenGL Shading language use Getting ready There's not much to prepare for with this one, you just need to build an environment that supports C++. Also, I'll assume that you are using GLM for matrix and vector support. If not, just leave out the functions involving the GLM classes. The reader would benefit from the previous articles on Tips and Tricks for Getting Started with OpenGL and GLSL 4.0 and OpenGL 4.0: Using Uniform Blocks and Uniform Buffer Objects. How to do it... We'll use the following header file for our C++ class: namespace GLSLShader { enum GLSLShaderType { VERTEX, FRAGMENT, GEOMETRY,TESS_CONTROL, TESS_EVALUATION }; }; class GLSLProgram { private: int handle; bool linked; string logString; int getUniformLocation(const char * name ); bool fileExists( const string & fileName ); public: GLSLProgram(); bool compileShaderFromFile( const char * fileName, GLSLShader::GLSLShaderType type ); bool compileShaderFromString( const string & source, GLSLShader::GLSLShaderType type ); bool link(); void use(); string log(); int getHandle(); bool isLinked(); void bindAttribLocation( GLuint location, const char * name); void bindFragDataLocation( GLuint location, const char * name ); void setUniform(const char *name,float x,float y, float z); void setUniform(const char *name, const vec3 & v); void setUniform(const char *name, const vec4 & v); void setUniform(const char *name, const mat4 & m); void setUniform(const char *name, const mat3 & m); void setUniform(const char *name, float val ); void setUniform(const char *name, int val ); void setUniform(const char *name, bool val ); void printActiveUniforms(); void printActiveAttribs(); }; The techniques involved in the implementation of these functions are covered in previous recipes. (Code available here). We'll discuss some of the design decisions in the next section. How it works... The state stored within a GLSLProgram object includes the handle to the OpenGL shader program object (handle), a Boolean variable indicating whether or not the program has been successfully linked (linked), and a string for storing the most recent log produced by a compile or link action (logString). The two private functions are utilities used by other public functions. The getUniformLocation function is used by the setUniform functions to find the location of a uniform variable, and the fileExists function is used by compileShaderFromFile to check for file existence. The constructor simply initializes linked to false, handle to zero, and logString to the empty string. The variable handle will be initialized by calling glCreateProgram when the first shader is compiled. The compileShaderFromFile and compileShaderFromString functions attempt to compile a shader of the given type (the type is provided as the second argument). They create the shader object, load the source code, and then attempt to compile the shader. If successful, the shader object is attached to the OpenGL program object (by calling glAttachShader) and a value of true is returned. Otherwise, the log is retrieved and stored in logString, and a value of false is returned. The link function simply attempts to link the program by calling glLinkProgram. It then checks the link status, and if successful, sets the variable linked to true and returns true. Otherwise, it gets the program log (by calling glGetProgramInfoLog), stores it in logString, and returns false. The use function simply calls glUseProgram if the program has already been successfully linked; otherwise, it does nothing. The log function returns the contents of logString, which should contain the log of the most recent compile or link action. The functions getHandle and isLinked are simply "getter" functions that return the handle to the OpenGL program object and the value of the linked variable. The functions bindAttribLocation and bindFragDataLocation are wrappers around glBindAttribLocation and glBindFragDataLocation. Note that these functions should only be called prior to linking the program. The setUniform overloaded functions are straightforward wrappers around the appropriate glUniform functions. Each of them calls getUniformLocation to query for the variable's location before calling the glUniform function. Finally, the printActiveUniforms and printActiveAttribs functions are useful mainly for debugging purposes. They simply display a list of the active uniforms/attributes to standard output. The following is a simple example of the use of the GLSLProgram class: GLSLProgram prog; if( ! prog.compileShaderFromFile("myshader.vert", GLSLShader::VERTEX)) { printf("Vertex shader failed to compile!n%s", prog.log().c_str()); exit(1); } if( ! prog.compileShaderFromFile("myshader.frag", GLSLShader::FRAGMENT)) { printf("Fragment shader failed to compile!n%s", prog.log().c_str()); exit(1); } // Possibly call bindAttribLocation or bindFragDataLocation // here... if( ! prog.link() ) { printf("Shader program failed to link!n%s", prog.log().c_str()); exit(1); } prog.use(); prog.printActiveUniforms(); prog.printActiveAttribs(); prog.setUniform("ModelViewMatrix", matrix); prog.setUniform("LightPosition", 1.0f, 1.0f, 1.0f); ... Summary This article covered the topic of Building a C++ Shader Program Class. Further resources on this subject: OpenGL 4.0: Using Uniform Blocks and Uniform Buffer Objects [Article] Tips and Tricks for Getting Started with OpenGL and GLSL 4.0 [Article] The Basics of GLSL 4.0 Shaders [Article] GLSL 4.0: Using Subroutines to Select Shader Functionality [Article] GLSL 4.0: Discarding Fragments to Create a Perforated Look [Article]
Read more
  • 0
  • 0
  • 6683

article-image-biztalk-application-dynamics-ax-message-outflow
Packt
03 Aug 2011
4 min read
Save for later

BizTalk Application: Dynamics AX Message Outflow

Packt
03 Aug 2011
4 min read
  Microsoft BizTalk 2010: Line of Business Systems Integration A practical guide to integrating Line of Business systems with BizTalk Server 2010 We found that rather than repeating code in several BizTalk solutions when you need to retrieve data from the AIF Queue, it's relatively simple to create a general solution to accomplish this. This solution will retrieve all data via the BizTalk Dynamics AX adapter by polling the Queue at a set interval of time. The minimum polling interval is 1 minute, thus any messages you put in the AIF Queue will not be immediately consumed by BizTalk. The complete solution (Chapter9-AXMessageOutflow) is included with the source code. We'll start by creating a new BizTalk project, Chapter9-AXMessageOutflow, in Visual Studio. Add in a new orchestration, ProcessOutboundAXMessage.odx, which will be the only orchestration required for this example. Also, we'll need to add reference to the Microsoft.Dynamics.BizTalk.Adapter.Schemas assembly and sign the project with a strong name key.   Message setup Next, we'll add two messages to our orchestration: msgAxOutboundMessage and msgAXDocument. These will be the only two messages required in this example. The first message, msgAXOutboundMessage, is of type DynamicsAX5.Message.Envelope. The schema is located in the referenced Microsoft.Dynamics.BizTalk.Adapter.Schemas assembly. (Move the mouse over the image to enlarge.) All outbound messages from the AIF Queue are of this type. As you can see from the sample screenshot below, we have some metadata in the header node but what we are really interested in is the XML contents of the Body node. The contents of the MessageParts node in the Body node will be of type ExchangeRatesService_ExchangeRates.xsd. Thus, all the schemas we require for both inbound and outbound transactions can be generated using the adapter. For the second message, since we don't want to specify a document type, we will use System.Xml.XmlDocument for the Message Type. Using the System.Xml.XmlDocument message type allows for great flexibility in this solution. We can push any message to the AIF queue, and no changes to this BizTalk application are required. Only changes to consuming applications may need to add the AX schema of the message in order to process it. Orchestration setup Next, we create a new a logical port that will receive all messages from Dynamics AX via the AIF Queue with the following settings: Port NameReceiveAXOutboundMessage_PortPort Type NameReceiveAXOutboundMessage_PortTypeCommunication PatternOne-WayPort direction of communicationI'll always be receiving messages on this portPort BindingSpecify Later Also, create a new send port. For this example, we'll just send to a folder drop using the FILE adapter so that we can easily view the XML documents. In practice, other BizTalk applications will most likely process these messages, so you may choose to modify the send port to meet your requirements. Send port settings: Port NameSendAXDocument_PortPort Type NameSendAXDocument_PortTypeCommunication PatternOne-WayPort direction of communicationI'll always be sending messages on this portPort BindingSpecify Later Next, we will need to add the following to the orchestration: Receive shape (receive msgAXOutboundMessage message) Expression shape (determine the file name for msgAXDocument) Message assignment (construct msgAXDocument message) Send shape (send msgAXDocument message) We'll also add two variables (aifActionName and xpathExpression) of type System.String and xmlDoc of type System.Xml.XmlDocument. In the expression shape, we want to extract the AIF Action so that we can name the outbound XML documents in a similar fashion. This will allow us to easily identify the message type from AX. Next, we'll put the following inside expression shape below receive to extract the AIF action name. aifActionName = msgAXOutboundMessage(DynamicsAx5.Action); aifActionName = aifActionName.Substring(55,aifActionName. LastIndexOf('/') - 55); Now, we need to extract the contents of the body message, which is the XML document that we are interested in. Inside the message assignment shape, we will use XPath to extract the message. What we are interested in is the contents of the Body node in the DynamicsAX5.Message.Envelope message we will receive from AX via the AIF Queue. Add the following code inside the assignment shape to extract the XML, assign it to the message we are sending out, and set a common name that we can use in our send port: // Extract Contents of Body node in Envelope Message xpathExpression = "/*[local-name()='Envelope' and namespaceuri()=' http://schemas.microsoft.com/dynamics/2008/01/documents/ Message']/*[local-name()='Body' and namespace-uri()='http://schemas.microsoft.com/dynamics/2008/01/ documents/Message']"; xmlDoc = xpath(msgAXOutboundMessage, xpathExpression); // Extract the XML we are interested in xmlDoc.LoadXml(xmlDoc.FirstChild.FirstChild.InnerXml); // Set the message to the XML Document msgAXDocument = xmlDoc; // Assign FILE.ReceivedFileNameproperty msgAXDocument(FILE.ReceivedFileName) = aifActionName;  
Read more
  • 0
  • 0
  • 2447

article-image-opengl-40-using-uniform-blocks-and-uniform-buffer-objects
Packt
03 Aug 2011
10 min read
Save for later

OpenGL 4.0: Using Uniform Blocks and Uniform Buffer Objects

Packt
03 Aug 2011
10 min read
  OpenGL 4.0 Shading Language Cookbook Over 60 highly focused, practical recipes to maximize your OpenGL Shading language use         Read more about this book       If your OpenGL/GLSL program involves multiple shader programs that use the same uniform variables, one has to manage the variables separately for each program. Uniform blocks were designed to ease the sharing of uniform data between programs. In this article by David Wolff, author of OpenGL 4.0 Shading Language Cookbook, we will create a buffer object for storing the values of all the uniform variables, and bind the buffer to the uniform block. Then when changing programs, the same buffer object need only be re-bound to the corresponding block in the new program. (For more resources on this subject, see here.) Uniform locations are generated when a program is linked, so the locations of the uniforms may change from one program to the next. The data for those uniforms may have to be re-generated and applied to the new locations. A uniform block is simply a group of uniform variables defined within a syntactical structure known as a uniform block. For example, in this recipe, we'll use the following uniform block: uniform BlobSettings { vec4 InnerColor; vec4 OuterColor; float RadiusInner; float RadiusOuter;}; This defines a block with the name BlobSettings that contains four uniform variables. With this type of block definition, the variables within the block are still part of the global scope and do not need to be qualified with the block name. The buffer object used to store the data for the uniforms is often referred to as a uniform buffer object. We'll see that a uniform buffer object is simply just a buffer object that is bound to a certain location. For this recipe, we'll use a simple example to demonstrate the use of uniform buffer objects and uniform blocks. We'll draw a quad (two triangles) with texture coordinates, and use our fragment shader to fill the quad with a fuzzy circle. The circle is a solid color in the center, but at its edge, it gradually fades to the background color, as shown in the following image. Getting ready Start with an OpenGL program that draws two triangles to form a quad. Provide the position at vertex attribute location 0, and the texture coordinate (0 to 1 in each direction) at vertex attribute location 1 (see: Sending data to a shader using per-vertex attributes and vertex buffer objects). We'll use the following vertex shader: #version 400 layout (location = 0) in vec3 VertexPosition;layout (location = 1) in vec3 VertexTexCoord; out vec3 TexCoord; void main(){ TexCoord = VertexTexCoord; gl_Position = vec4(VertexPosition,1.0);} The fragment shader contains the uniform block, and is responsible for drawing our fuzzy circle: #version 400in vec3 TexCoord;layout (location = 0) out vec4 FragColor; uniform BlobSettings { vec4 InnerColor; vec4 OuterColor; float RadiusInner; float RadiusOuter;}; void main() { float dx = TexCoord.x - 0.5; float dy = TexCoord.y - 0.5; float dist = sqrt(dx * dx + dy * dy); FragColor = mix( InnerColor, OuterColor, smoothstep( RadiusInner, RadiusOuter, dist ) );} The uniform block is named BlobSettings. The variables within this block define the parameters of our fuzzy circle. The variable OuterColor defines the color outside of the circle. InnerColor is the color inside of the circle. RadiusInner is the radius defining the part of the circle that is a solid color (inside the fuzzy edge), and the distance from the center of the circle to the inner edge of the fuzzy boundary. RadiusOuter is the outer edge of the fuzzy boundary of the circle (when the color is equal to OuterColor). The code within the main function computes the distance of the texture coordinate to the center of the quad located at (0.5, 0.5). It then uses that distance to compute the color by using the smoothstep function. This function provides a value that smoothly varies between 0.0 and 1.0 when the value of the third argument is between the values of the first two arguments. Otherwise it returns 0.0 or 1.0 depending on whether it is less than the first or greater than the second, respectively. The mix function is then used to linearly interpolate between InnerColor and OuterColor based on the value returned by the smoothstep function. How to do it... In the OpenGL program, after linking the shader program, use the following steps to send data to the uniform block in the fragment shader: Get the index of the uniform block using glGetUniformBlockIndex. GLuint blockIndex = glGetUniformBlockIndex(programHandle, "BlobSettings"); Allocate space for the buffer to contain the data for the uniform block. We get the size of the block using glGetActiveUniformBlockiv. GLint blockSize; glGetActiveUniformBlockiv(programHandle, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize); GLubyte * blockBuffer= (GLubyte *) malloc(blockSize); Query for the offset of each variable within the block. To do so, we first find the index of each variable within the block. // Query for the offsets of each block variableconst GLchar *names[] = { "InnerColor", "OuterColor", "RadiusInner", "RadiusOuter" }; GLuint indices[4];glGetUniformIndices(programHandle, 4, names, indices); GLint offset[4];glGetActiveUniformsiv(programHandle, 4, indices, GL_UNIFORM_OFFSET, offset); Place the data into the buffer at the appropriate offsets. GLfloat outerColor[] = {0.0f, 0.0f, 0.0f, 0.0f};GLfloat innerColor[] = {1.0f, 1.0f, 0.75f, 1.0f};GLfloat innerRadius = 0.25f, outerRadius = 0.45f; memcpy(blockBuffer + offset[0], innerColor, 4 * sizeof(GLfloat));memcpy(blockBuffer + offset[1], outerColor, 4 * sizeof(GLfloat));memcpy(blockBuffer + offset[2], &innerRadius, sizeof(GLfloat));memcpy(blockBuffer + offset[3], &outerRadius, sizeof(GLfloat)); Create the OpenGL buffer object and copy the data into it. GLuint uboHandle;glGenBuffers( 1, &uboHandle );glBindBuffer( GL_UNIFORM_BUFFER, uboHandle );glBufferData( GL_UNIFORM_BUFFER, blockSize, blockBuffer, GL_DYNAMIC_DRAW ); Bind the buffer object to the uniform block. glBindBufferBase( GL_UNIFORM_BUFFER, blockIndex, uboHandle ); How it works... Phew! This seems like a lot of work! However, the real advantage comes when using multiple programs where the same buffer object can be used for each program. Let's take a look at each step individually. First, we get the index of the uniform block by calling glGetUniformBlockIndex, then we query for the size of the block by calling glGetActiveUniformBlockiv. After getting the size, we allocate a temporary buffer named blockBuffer to hold the data for our block. The layout of data within a uniform block is implementation dependent, and implementations may use different padding and/or byte alignment. So, in order to accurately layout our data, we need to query for the offset of each variable within the block. This is done in two steps. First, we query for the index of each variable within the block by calling glGetUniformIndices. This accepts an array of variable names (third argument) and returns the indices of the variables in the array indices (fourth argument). Then we use the indices to query for the offsets by calling glGetActiveUniformsiv. When the fourth argument is GL_UNIFORM_OFFSET, this returns the offset of each variable in the array pointed to by the fifth argument. This function can also be used to query for the size and type; however, in this case we choose not to do so, to keep the code simple (albeit less general). The next step involves filling our temporary buffer blockBuffer with the data for the uniforms at the appropriate offsets. Here we use the standard library function memcpy to accomplish this. Now that the temporary buffer is populated with the data with the appropriate layout, we can create our buffer object and copy the data into the buffer object. We call glGenBuffers to generate a buffer handle, and then bind that buffer to the GL_UNIFORM_BUFFER binding point by calling glBindBuffer. The space is allocated within the buffer object and the data is copied when glBufferData is called. We use GL_DYNAMIC_DRAW as the usage hint here, because uniform data may be changed somewhat often during rendering. Of course, this is entirely dependent on the situation. Finally, we associate the buffer object with the uniform block by calling glBindBufferBase. This function binds to an index within a buffer binding point. Certain binding points are also so-called "indexed buffer targets". This means that the target is actually an array of targets, and glBindBufferBase allows us to bind to one index within the array. There's more... If the data for a uniform block needs to be changed at some later time, one can call glBufferSubData to replace all or part of the data within the buffer. If you do so, don't forget to first bind the buffer to the generic binding point GL_UNIFORM_BUFFER. Using an instance name with a uniform block A uniform block can have an optional instance name. For example, with our BlobSettings block, we could have used the instance name Blob, as shown here: uniform BlobSettings { vec4 InnerColor; vec4 OuterColor; float RadiusInner; float RadiusOuter;} Blob; In this case, the variables within the block are placed within a namespace qualified by the instance name. Therefore our shader code needs to refer to them prefixed with the instance name. For example: FragColor = mix( Blob.InnerColor, Blob.OuterColor, smoothstep( Blob.RadiusInner, Blob.RadiusOuter, dist ) ); Additionally, we need to qualify the variable names within the OpenGL code when querying for variable indices. The OpenGL specification says that they must be qualified with the block name (BlobSettings). However, my tests using the ATI Catalyst (10.8) drivers required me to use the instance name (Blob). Using layout qualifiers with uniform blocks Since the layout of the data within a uniform buffer object is implementation dependent, it required us to query for the variable offsets. However, one can avoid this by asking OpenGL to use the standard layout std140. This is accomplished by using a layout qualifier when declaring the uniform block. For example: layout( std140 ) uniform BlobSettings { ...}; The std140 layout is described in detail within the OpenGL specification document (available at http://www.opengl.org). Other options for the layout qualifier that apply to uniform block layouts include packed and shared. The packed qualifier simply states that the implementation is free to optimize memory in whatever way it finds necessary (based on variable usage or other criteria). With the packed qualifier, we still need to query for the offsets of each variable. The shared qualifier guarantees that the layout will be consistent between multiple programs and program stages provided that the uniform block declaration does not change. If you are planning to use the same buffer object between multiple programs and/or program stages, it is a good idea to use the shared option. There are two other layout qualifiers that are worth mentioning: row_major and column_major. These define the ordering of data within the matrix type variables within the uniform block. One can use multiple qualifiers for a block. For example, to define a block with both the row_major and shared qualifiers, we would use the following syntax: layout( row_major, shared ) uniform BlobSettings { ...}; Summary This article covered the topic of Using Uniform Blocks and Uniform Buffer Objects. Further resources on this subject: OpenGL 4.0: Building a C++ Shader Program Class [Article] Tips and Tricks for Getting Started with OpenGL and GLSL 4.0 [Article] The Basics of GLSL 4.0 Shaders [Article] GLSL 4.0: Using Subroutines to Select Shader Functionality [Article] GLSL 4.0: Discarding Fragments to Create a Perforated Look [Article]
Read more
  • 0
  • 0
  • 21735
article-image-integrating-microsoft-dynamics-ax-2009-using-biztalk-adapter
Packt
03 Aug 2011
5 min read
Save for later

Integrating with Microsoft Dynamics AX 2009 using BizTalk Adapter

Packt
03 Aug 2011
5 min read
  Microsoft BizTalk 2010: Line of Business Systems Integration What is Dynamics AX? Microsoft Dynamics AX (formally Microsoft Axapta) is Microsoft's Enterprise Resource Planning (ERP) solution for mid-size and large customers. Much like SAP, Dynamics AX provides functions that are critical to businesses that can benefit from BizTalk's integration. Microsoft Dynamics AX is fully customizable and extensible through its rich development platform and tools. It has direct connections to products such as Microsoft BizTalk Server, Microsoft SQL Server, Exchange, and Office. Often Dynamics AX is compared to SAP All in One. Those who are familiar with SAP are also familiar with high cost of implementation, maintenance, and customization associated with it. A Microsoft Dynamics AX solution offers more customizability, lower maintenance costs, and lower per-user costs than SAP. ERP implementations often fail in part due to lack of user acceptance in adopting a new system. The Dynamics AX user interface has a similar look and feel to other widely used products such as Microsoft Office and Microsoft Outlook, which significantly increases the user's comfort level when dealing with a new ERP system. For more information on Dynamics AX 2009 and SAP, please see http://www.microsoft.com/dynamics/en/us/compare-sap.aspx. Methods of integration with AX Included with Dynamics AX 2009, Microsoft provides two tools for integration with Dynamics AX: Dynamics AX BizTalk Adapter .NET Business Connector The BizTalk adapter interfaces via the Application Interface Framework Module (AIF) in Dynamics AX 2009, and the .NET Business Connector directly calls the Application Object Tree (AOT) classes in your AX source code. The AIF module requires a license key, which can add cost to your integration projects if your organization has not purchased this module. It provides an extensible framework that enables integration via XML document exchange. A great advantage of the AIF module is its integration functionality with the BizTalk Dynamics AX adapter. Other adapters include a FILE adapter and MSMQ, as well as Web Services to consume XML files are included out of the box. The AIF module requires a fair amount of setup and configuration. Other advantages include full and granular security, capability of synchronous and asynchronous mode integration mode, and full logging of transactions and error handling. The Microsoft BizTalk AX 2009 adapter can execute AX actions (exposed functions to the AIF module) to write data to AX in both synch and asynch modes. Which mode is used is determined by the design of your BizTalk application (via logical ports). A one-way send port will put the XML data into the AIF queue, whereas a two-way send-receive port will execute the actions and return a response message. Asynch transitions will stay in the AIF queue until a batch job is executed. Setting up and executing the batch jobs can be very difficult to manage. Pulling data from AX can also be achieved using the BizTalk adapter. Transactions pushed into the same AIF queue (with an OUTBOUND direction in an async mode) can be retrieved using the AX adapter which polls AX for these transactions. The .NET Business connector requires custom .NET code to be written in order to implement it. If your business requirements are for a single (or very small amount) of point-to-point integration data flows, then we would recommend using the .NET Business Connector. However, this often requires customizations in order to create and expose the methods. Security also needs to be handled with the service account that the code is running under. Installing the adapter and .NET Business Connector The Microsoft BizTalk adapter for Dynamics AX 2009 and the .NET Business Connector are installed from your Dynamics AX Setup install setup under Integration on the Add or Modify components window. Each component is independent of one another; however the BizTalk adapter leverages components of the business connector. You are not required to install the Dynamics AX client on the BizTalk server. When installed in BizTalk adapter, you can simply select all the defaults from the install wizard. For the .NET business connector, you'll be prompted for the location of your Dynamics AX instance. This will be used only as a default configuration and can easily be changed. Configuring Dynamics AX 2009 Application Integration Framework for BizTalk Adapter Configuration of the AIF module involves several steps. It also goes a long way to increasing your understanding of the granularity of Dynamics AX setup and security considerations that were taken into account for integration of what can be highly sensitive data.It is recommended that this setup be done with Admin level security, however, only full control of the AIF module is required. This setup is almost identical in version prior to Dynamics AX 2009; minor differences will be noted. All AIF setup tables can be found in Dynamics AX under Basic | Setup | Application Integration Framework. The first step is rather simple, however critical. In the Transport Adapters form, add in a new entry selecting Adapter Class drop down AifBizTalkAdapter, select Active, and Direction will be Receive and Respond. You also notice there are two other out-of-the-box adapters: FILE and MSMQ. This is a one-time setup that is effective across all companies. Next, using the Channels form, set up an active channel for your specific BizTalk server. Select a meaningful and identifiable Channel ID and Name such as BizTalkChannelID and BizTalkChannel. Select the Adapter to BizTalk Adapter, check Active, set Direction to Both, Response channel equal to the Channel ID of BizTalkChannelID. Set the Address to your BizTalk Server (I2CDARS1 as shown below). (Move the mouse over the image to enlarge.)  
Read more
  • 0
  • 0
  • 3988

article-image-play-framework-binding-and-validating-objects-and-rendering-json-output
Packt
03 Aug 2011
4 min read
Save for later

Play Framework: Binding and Validating Objects and Rendering JSON Output

Packt
03 Aug 2011
4 min read
Binding and validating objects using custom binders Read the Play documentation about binding and validating objects. As validation is extremely important in any application, it basically has to fulfill several tasks. First, it should not allow the user to enter wrong data. After a user has filled a form, he should get a positive or negative feedback, irrespective of whether the entered content was valid or not. The same goes for storing data. Before storing data you should make sure that storing it does not pose any future problems as now the model and the view layer should make sure that only valid data is stored or shown in the application. The perfect place to put such a validation is the controller. As a HTTP request basically is composed of a list of keys and values, the web framework needs to have a certain logic to create real objects out of this argument to make sure the application developer does not have to do this tedious task. You can find the source code of this example in the chapter2/binder directory. How to do it... Create or reuse a class you want created from an item as shown in the following code snippet: public class OrderItem { @Required public String itemId; public Boolean hazardous; public Boolean bulk; public Boolean toxic; public Integer piecesIncluded; public String toString() { return MessageFormat.format("{0}/{1}/{2}/{3}/{4}", itemId, piecesIncluded, bulk, toxic, hazardous); } } Create an appropriate form snippet for the index.xml template: #{form @Application.createOrder()} <input type="text" name="item" /><br /> <input type="submit" value="Create Order"> #{/form} Create the controller: public static void createOrder(@Valid OrderItem item) { if (validation.hasErrors()) { render("@index"); } renderText(item.toString()); } Create the type binder doing this magic: @Global public class OrderItemBinder implements TypeBinder<OrderItem> { @Override public Object bind(String name, Annotation[] annotations, String value, Class actualClass) throws Exception { OrderItem item = new OrderItem(); List<String> identifier = Arrays.asList(value.split("-", 3)); if (identifier.size() >= 3) { item.piecesIncluded = Integer.parseInt(identifier.get(2)); } if (identifier.size() >= 2) { int c = Integer.parseInt(identifier.get(1)); item.bulk = (c & 4) == 4; item.hazardous = (c & 2) == 2; item.toxic = (c & 1) == 1; } if (identifier.size() >= 1) { item.itemId = identifier.get(0); } return item; } } How it works... With the exception of the binder definition all of the preceding code has been seen earlier. By working with the Play samples you already got to know how to handle objects as arguments in controllers. This specific example creates a complete object out of a simple String. By naming the string in the form value (<input …name="item" />) the same as the controller argument name (createOrder(@Valid OrderItem item)) and using the controller argument class type in the OrderItemBinder definition (OrderItemBinder implements TypeBinder<OrderItem>), the mapping is done. The binder splits the string by a hyphen, uses the first value for item ID, the last for piìesIncluded, and checks certain bits in order to set some Boolean properties. By using curl you can verify the behavior very easily as shown: curl -v -X POST --data "item=Foo-3-5" localhost:9000/order Foo/5/false/true/true Here Foo resembles the item ID, 5 is the piecesIncluded property, and 3 is the argument means that the first two bits are set and so the hazardous and toxic properties are set, while bulk is not. There's more... The TypeBinder feature has been introduced in Play 1.1 and is documented at http://www.playframework.org/documentation/1.2/controllers#custombinding. Using type binders on objects Currently, it is only possible to create objects out of one single string with a TypeBinder. If you want to create one object out of several submitted form values you will have to create your own plugin for this as workaround. You can check more about this at: http://groups.google.com/group/play-framework/browse_thread/thread/62e7fbeac2c9e42d Be careful with JPA using model classes As soon as you try to use model classes with a type binder you will stumble upon strange behavior, as your objects will always only have null or default values when freshly instanced. The JPA plugin already uses a binding and overwrites every binding you are doing.
Read more
  • 0
  • 0
  • 6207
Modal Close icon
Modal Close icon