Managing Metadata with Master Data Services – Part 1
This is the first in a series of blog entries that will discuss how to manage metadata as master data using Microsoft’s Master Data Services. In this first entry we discuss metadata as master data provide an Introduction to Master Data Services capabilities and what are its key components.
Meta data is data about data. Organizations employ many methods for managing their metadata (file systems, databases, spreadsheets, enterprise content management applications, etc.). There are also different types of metadata:
-
Technical metadata
- Line of Business applications
- Database schemas
- Development standards and conventions
-
Business metadata
- Business concepts
- Business entities
- Business processes
For both types of aforementioned metadata, related processes change, organizations evolve and technologies come and go. The question is how to manage these changes with respect to organizational metadata.
Typically master data would consist of business entities, their associated attributes and members; for instance, a customer master consisting of a list of customer attributes and customers. But what defines a customer. What is its context and how does it evolve over time. I submit that organizational metadata should be treated as master data and a formal tool and process should be used to manage it.
One such tool is Microsoft’s Master Data Services. Master Data Services provides the following capabilities:
- Centralized hub for storing authoritative and certified data
- Supports implementation of business rules and workflows for maintaining data quality
- Supports hierarchies and attribute level domain constraints
- Role based security
- Multiple user interfaces (Web, Excel 2010)
- Model for batch imports and exports to/from external systems
The following figure defines the basic steps in defining, developing and maintaining our master data services solution. In this post we will only address master data structures as they relate to metadata.
The following data structures are available and need to be defined within Master Data Services:
Models – Models organize the structure of your master data. You can have one or many models. In the case of metadata the model will be a container for concepts. For example, the model would be the metadata model defining the concepts of Business Entity Metadata, Attribute Entity Metadata, etc.
Entities – An entity is a container for the attributes, attribute groups, hierarchies and collections that define a specific concept. There can be as many entities as required to fully define the concept. In the case of metadata there can be an entity defined as follows from a membership perspective:
Where
Business Entity Metadata – The name of the entity
Name – The entity being defined (Customer, Product, Account, etc.)
Description – Definition of the entity (Customer is an individual or organization that purchases our products)
Owner – The name of the individual or organization responsible the definition of the entity
Attributes – Attributes can be viewed as columns within an entity. In the case of our Metadata model and our entity Business Metadata Entity we would have the following:
|
Business Entity Metadata |
||
|
Name |
Description |
Owner |
|
Customer |
An individual or organization that purchases our goods or services |
Customer Service |
|
Account |
A cost collection point defining cash flow into and out of the organization |
Finance |
|
Product |
A manufactured good or a service sold to a Customer |
Operations |
Attribute Groups – An Attribute Group provides the ability to manage attributes by grouping them into tabs. From a usability perspective this becomes important when there are a large number of attributes need to be viewed. Attributes can be logically group based on their relationship to one another.
Domain Based Attributes - A domain-based attribute is an attribute with values that are populated by members from another entity. You can think of a domain-based attribute as a constrained list; domain-based attributes prevent users from entering attribute values that are not valid. To select an attribute value, the user must pick from a list. The domain-based attribute can be used in multiple entities.
Once the structures have been built, it is now time to populate them with data. In the next post we will fully define all the metadata entities and discuss their relationships to one another and the types of data that will populate them.
Incorporating SQL 2012 Columnstore Indexes into your BI Strategy
test
“Attempted to perform an unauthorized operation” and SPWeb.DoesUseHavePermissions
string url = "http://myfarm";
SPSecurity.RunWithElevatedPrivileges(delegate
{
using(SPSite s = new SPSite(url)
{
bool hasPermissions =
s.RootWeb.DoesUserHavePermissions(
SPContext.Current.Web.CurrentUser,
SPBasePermissions.ViewPages);
if(hasPermissions)
{
// do something useful
}
}
}
When I first tested the above code locally on my machine it worked perfectly. This is not uncommon because my local environment was not as complex as the production machine (multiple servers, application pools, service accounts, etc). Well when I deployed my code to the Dev server farm and tested it I got a correlation id which lead me to the stack trace beginning with "Attempted to perform an unauthorized operation".
After scratching my head as to what was different on my local farm from the Dev server farm I found the problem was being caused because the server has multiple web applications each running with their own service account and application pool (as it should with a good server design). What was unique is that my code was running in Web App [A] and the site I was trying to query and check permissions on was running in Web App [B].
What is confusing is why is there an unauthorized operation when I am using a RunWithElevatedPrivileges delegate which should be running the contained code using..well "elevated privileges". Since the SharePoint architect is certainly not going to redesign the farm because my code was not cooperating I had to find another solution. Thankfully there was a simple solution:
string url = "http://myfarm";
SPSecurity.RunWithElevatedPrivileges(delegate
{
using(SPSite s = new SPSite(url, SPUserToken.SystemAccount)
{
bool hasPermissions =
s.RootWeb.DoesUserHavePermissions(
SPContext.Current.Web.CurrentUser,
SPBasePermissions.ViewPages);
if(hasPermissions)
{
// do something useful
}
}
}
So apparently SPSite has a constructor that allows you to provide the SPUserToken of an account to use to open the SPSite with, in my case the SPUserToken.SystemAccount static property. After making this one change everything was worked perfectly both locally on my machine and on the Dev server.
Final Note
You may have noticed that I kept the RunWithElevatedPrivileges delegate even after utilizing the new SPSite constructor, techincally this is overkill and would not be necessary because you should use one or the other. In my case the "do something useful" part of my code still required the RunWithElevatedPrivileges delegate so I’m using both. If you are only accessing the SPSite object and related members you can probably get away with just the other SPSite constructor, like everything you need to look at what you’re actually trying to accomplish to see what makes the most sense for you.
References
BizTalk Build and Deployment – Part 2
Continuing
onto from last blog
post on building and deploying BizTalk Solutions, in this series we will look
into Build Script and the Framework for the same which uses Msbuild
Task/Target.
Pre-requisite
for our Build solution ( to include Packaging ) is MsBuildCommunity Task ( http://msbuildtasks.tigris.org/ ).
As
goes with any framework based "Generic" approach, it is recommended
although not required to follow some naming guidelines/standards. Following the best practices for BizTalk
Solutions, it is typically recommended to have a separate project for each
BizTalk Artifacts. We will make an
assumption here that our project naming structure is
- <ProjectName>.Orchestration
- <ProjectName>.Schemas
- <ProjectName>.Pipelines
- <ProjectName>.Components
- <ProjectName>.PipelineComponents
- <ProjectName>.Transforms
With
Solution name as <ProjectName>.sln
Let’s
revisit and go in detail on our BtFramework.Target ( Common MSBuild task/target
)
Import
the MsBuild Community Task and Targets ( Line 2 ).
Line
4 we have defined our Target which will do actual Build. We are using a standard MSBuild command
specifiying name of our solution. For
every single solution that we built it will have it’s own Build/Deployment file
in which we will specify the configuration ( ProjectSolutionName ) specific
values. Upon successful build we call
another target ( Line 9 ) to perform unit test for our project
UnitTest
target is using a standard mstest ( or we could also use Nunit ) executable to
perform unit test defined in our Project/Solution
Typically
once the build is completed successfully, we would like to package the solution
for the administrator to deploy onto different environment. That’s where CopyRequiredFiles ( 14 ) target
comes into play. Idea here is to make
sure when the package/archive is built it has all required components within
the package for independent deployment onto remote server/another server.
Lastly
we have ZipPackage target which creates a list of all file(s) and/or directory
and uses Zip Task ( part of MsBuildCommunity ) to create package with an
ability to archive the older build packages.
- <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="MsBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
- <Target Name="Integration" DependsOnTargets="Build;CopyRequiredFiles;ZipPackage"/>
- <Target Name="Build">
- <Exec Command=‘rd /s /q
"$(TestOutputPath)"‘ /> - <Exec Command=‘md
"$(TestOutputPath)\$(Configuration)"‘ />
- <MSBuild Projects="$(ProjectSolutionName)"
- Targets="Rebuild"
- Properties="Configuration=$(Configuration);OutputPath=$(TestOutputPath)\$(Configuration);" Condition="‘$(FullBuild)’ == ‘true’"/>
- <CallTarget Targets="UnitTest"/>
- </Target>
- <Target Name="UnitTest">
- <Exec Command="mstest.exe
/testcontainer:$(TestOutputPath)\$(Configuration)\$(ProjectName).Tests.dll" ContinueOnError="true"/>
- </Target>
- <Target Name="CopyRequiredFiles" DependsOnTargets="CopyLibFolders"/>
- <Target Name="CopyLibFolders">
- <Exec Command=‘xcopy
/Y /S "$(MSBuildProjectDirectory)\..\Lib"
"$(TestOutputPath)\$(Configuration)\..\..\Lib\*.*"‘/>
- </Target>
- <Target Name="ZipPackage">
- <!–
****************************************************************** –>
- <!– * Zip the
PackageOutputPath * –>
- <!–
****************************************************************** –>
- <Exec Command=‘xcopy /Y
"$(PackageOutputPath)\*.zip" "$(PackageArchivePath)" ‘ ContinueOnError=‘true‘/>
- <CreateItem Include="$(PackageOutputPath)\*.zip">
- <Output TaskParameter="Include" ItemName="DeleteZip"/>
- </CreateItem>
- <Delete Files="@(DeleteZip)" />
- <CreateItem Include="$(MSBuildProjectDirectory)\**\*.*">
- <Output TaskParameter="Include" ItemName="FilesToPackage"/>
- </CreateItem>
- <Time Format="yyyyMMddHHmmss">
- <Output TaskParameter="FormattedTime" PropertyName="CurrentDate" />
- </Time>
- <Zip Files="@(FilesToPackage)"
- WorkingDirectory="$(PackageOutputPath)"
- ZipFileName="$(PackageOutputPath)\Mps-Build-Sample-FullBuild-$(CurrentDate).zip"
- ZipLevel="9" Condition="‘$(FullBuild)’ == ‘true’"/>
- </Target>
- <Target Name="UnZipPackage">
- <!–
****************************************************************** –>
- <!– * UnZip the
PackageOutputPath * –>
- <!–
****************************************************************** –>
- <ItemGroup>
- <ZipFileName Include="$(PackageOutputPath)\*.zip" />
- </ItemGroup>
- <Unzip ZipFileName="%(ZipFileName.Identity)"
- TargetDirectory="c:\temp"/>
- </Target>
- </Project>
At
this point we have our base framework built for to do build, perform unit test,
copy required files and package the solution.
As we move along we will be modifying framework file for additional
advancement like building package with appropriate package version, generating
common assembly version and an option for Code coverage.
Let’s
look now into how can we use the framework file in our BizTalk Solution. Following is the msbuild file for our
project/solution.
- <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Integration">
- <PropertyGroup>
- <Configuration Condition="‘$(Configuration)’
== ”">Debug</Configuration> - <ProjectName>Mps.Build.Sample</ProjectName>
- <TestOutputPath>$(MSBuildProjectDirectory)\Bin</TestOutputPath>
- <ProjectSolutionName>$(MSBuildProjectDirectory)\..\$(ProjectName).sln</ProjectSolutionName>
- <FullBuild>True</FullBuild>
- <PackageOutputPath>$(MSBuildProjectDirectory)\..\Packages</PackageOutputPath>
- <PackageArchivePath>$(MSBuildProjectDirectory)\..\Packages\Archive</PackageArchivePath>
- </PropertyGroup>
- <Import Project="$(MSBuildProjectDirectory)\..\Lib\BtFramework.targets" />
- </Project>
Line
46 : Define the configuration that we want to build our solution in. If No configuration specified at the time of
the build, we default it to "Debug"
Line
47 : Essentially the name of our solution.
Line
48 : All assemblies that are built will be stored into \Bin Directory. It is this directory as well from where we
will be running our Unit Test ( if any )
Line
49 : Name of our solution ( which is <ProjectName>.sln )
Line
50 : For BizTalk solutions when it comes to deployment, there is always a need
for to do partial Deployment and we will be using this configuration parameter
further down to build *only* specific project and use that for deployment.
Line
51 : Directory where we want to store our Zip package
Line
52 : Directory where we will archive our current zip package
Line
54 : Import our BtFramework Task/Target file.
At
the time when we perform build using MsBuild, there is a way you can
change/specify properties ( /p )at runtime along with Target as well ( /t
parameter ). In Line 44, in the
scenario we have not specified target, we are going to use
"Integration" Target which is defined in our BtFramework.Target which
will do Build, copy required files and package the build.
Lastly
as mentioned in previous blog post, we could create a separate batch file for
building a Debug version or Release version
BuildDebug.bat
( Which invokes MSBuild )
MSBuild.exe
/p:Configuration=Debug Mps.Build.Sample.Build.btdfproj
BuildRelease.bat
MSBuild.exe
/p:Configuration=Release Mps.Build.Sample.Build.btdfproj
Full solution available @ https://skydrive.live.com/redir.aspx?cid=407628912e8c77b1&resid=407628912E8C77B1!127&parid=407628912E8C77B1!126&authkey=!AIkwMhI33-bCSIA
SQL Server 2012–Understanding the Pricing Changes
SQL Server 2012 officially launched on March 7, 2012. With the launch, Microsoft announced a new SKU as well as new pricing. The new pricing does not take effect until April 1, 2012 so there is a tremendous opportunity to purchase at the old pricing and use Software Assurance to receive an upgrade to the new product.
The release will be available in three main editions: Enterprise, Business Intelligence and Standard. The Enterprise is the all-inclusive database platform, with Microsoft saying it is ideal for mission-critical applications, large data warehouses and highly virtualized environments. The Standard Edition is for “departmental databases” and “limited business intelligence projects,” according to a vendor presentation. And the new Business Intelligence edition strikes a balance between the two. It is the Standard Edition with some added BI capabilities such as data quality, master data management and advanced analytics.
SQL Server 2012 licensing changes
With the different editions come options. One of the biggest changes with SQL Server 2012 pricing is that Microsoft is moving from processor-based to core-based licensing on Standard and Enterprise editions. It also will offer a server plus client access license (CAL) model on the Standard and Business Intelligence editions. The CAL license is increasing about 25%. As with all Microsoft pricing, you should contact your reseller for specifics based on your existing contract.
Under core-based licensing, you will have to license all the processing cores in a server, with a minimum of four licenses required for each physical processor in the server. So you should be running at least quad-core processor servers for SQL Server 2012; otherwise, you’ll be paying for core licenses that you aren’t using.
Here’s a rundown:
- Standard Edition: $734 per server plus $207 per CAL, or $6,874 per core
- Business Intelligence Edition: $7,026 per server plus $207 per CAL
- Enterprise Edition: $6,874 per core
The pricing per core in SQL Server 2012 is one-quarter the per-processor pricing in SQL Server 2008 R2. That means the cost of running SQL Server could go up if you’re running multi-core chips.
For example, let’s say you have an x86 server with two eight-core Intel Xeon processors. Previously, you would pay for two processor licenses at $27,495 per processor. Final cost: $54,990. But if you upgrade to SQL Server 2012, you’ll be paying for 16 processor cores at $6,874 per core. Final cost: $109,984, or about twice as much.
So as chipmakers continue to increase the number of cores in their processors, the cost of doing business on SQL Server 2012 will also rise if you have per-core licensing.
SQL Server 2012 pricing with virtualization
To license a virtual machine (VM) with core-based licenses, you can just pay for the virtual cores within the VM. But there is a minimum of four core licenses per VM. Each licensed VM covered under Microsoft’s Software Assurance program can be moved around on your physical server or to a private or public cloud.
If you have SQL Server 2012 Enterprise Edition with Software Assurance, you can deploy an unlimited amount of VMs on each server without having to pay more.
Take a look:
Migrating SQL Server 2012 licenses
If you’re running SQL Server 2008 R2 with Software Assurance, you can migrate your licenses to SQL Server 2012, as long as you do it by the end of June. Here’s a look at how licenses convert depending on your edition of SQL Server 2008 R2:
Anything Picker
We are all familiar with the people picker used in SharePoint web parts and application pages to find and select single or multi users from AD or any form authentication provider. The control is actually built to inherit from a more general purpose control named "EntityEditorWithPicker".
I will show how you can build a picker from any searchable source. The particular demo is for employees in a SQL table.
I learnt how to do this from http://www.chakkaradeep.com/post/SharePoint-Customising-the-EntityEditorWithPicker.aspx
So the steps to incorporate the custom control in SharePoint web parts and pages are:
-
Create a class file in the same project as the web parts and in it, Extend the 3 classes
- public class EmployeeEditor : EntityEditorWithPicker //This will be the reusable control
- CustomQueryControl : SimpleQueryControl //settings for the popup control
- public class CustomPickerDialog : PickerDialog // settings for the tabular results show
- In the "CustomQueryControl" class we can customize the popup dialog with several "search by" options. I used Name and job title but based on the context of the usage, it can be anything. Each "search by" will need its own search method but the results should be the same columns. In my demo it is the ID of the employee, his full name and job title.
- The CustomPickerDialog class is just settings for the tabular results to show columns names and width.
- The EmployeeEditor class is where most of the work is done. It has methods for search unique or lists and determine entries validation. There is also mapping of the results fields to the entity fields (key, display text and description. I chose the employee ID to be the key
- Once the classes are generated and built, the control can be used in web part and pages code like any web control. private EmployeeEditor eeEmployeeToFind = new EmployeeEditor(); off course all the attributes of the base are available. For example, I used MultiSelect to allow single or multiple results.
-
Since the control is not managed by the SharePoint’s project template, it will not get a "Safe control" line in the web.config file. And if you don’t add it yourself, you get:
-
VS2010 will make these web.config entries
- <SafeControl Assembly="Peters.Wirtz.HR.WebPartsI2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=58b09c82ceb21b3d" Namespace="Peters.Wirtz.HR.WebPartsI2.MultiEmployeeEdit" TypeName="*" Safe="True" SafeAgainstScript="True" />
- <SafeControl Assembly="Peters.Wirtz.HR.WebPartsI2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=58b09c82ceb21b3d" Namespace="Peters.Wirtz.HR.WebPartsI2.SearchEmployee" TypeName="*" Safe="True" SafeAgainstScript="False" />
- <SafeControl Assembly="Peters.Wirtz.HR.WebPartsI2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=58b09c82ceb21b3d" Namespace="Peters.Wirtz.HR.WebPartsI2.EditEmployee" TypeName="*" Safe="True" SafeAgainstScript="False" />
- <SafeControl Assembly="Peters.Wirtz.HR.WebPartsI2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=58b09c82ceb21b3d" Namespace="Peters.Wirtz.HR.WebPartsI2.TerminateEmployee" TypeName="*" Safe="True" SafeAgainstScript="False" />
- <SafeControl Assembly="Peters.Wirtz.HR.WebPartsI2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=58b09c82ceb21b3d" Namespace="Peters.Wirtz.HR.WebPartsI2.TransferEmployee" TypeName="*" Safe="True" SafeAgainstScript="False" />
- </SafeControls>
-
-
You need to add:
- <SafeControl Assembly="Peters.Wirtz.HR.WebPartsI2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=58b09c82ceb21b3d" Namespace="Peters.Wirtz.HR.WebPartsI2" TypeName="*" Safe="True" SafeAgainstScript="False" />
- Off course replace "Peters.Wirtz.HR.WebPartsI2" with your namespace
- Here is the code
BizTalk 2010 Tools
Microsoft Technet
has a Wiki Page
listing BizTalk Server 2010 Tools. It
has a nice set of compiled list of all Tools that are being used to help both
BizTalk Developers as well as Administrator
I usually like to
group those based on different phase(s) that they are used at in BizTalk Solution LifeCycle
Installation and Configuration
Performance/HealthCheck
Debugging/Monitoring
BizTalk
Instrumentation Framework
Development
BizTalk
Instrumentation Framework
Testing
Deployment
Powershell Provider for BizTalk
Administration
Feb 29th – Leap Day Bugs!!
Yesterday I was fighting some errors on my current project, a SharePoint 2010 Home page that was working perfectly fine the day before suddenly was crashing now. After the initial rundown of "what did we change yesterday, what changed on the server, etc." to make sure there wasn’t some new bug that we accidentally introduced to the Dev environment I dug into the trusty SharePoint ULS LOGS directory in the 14 root and found this:
Feb 29th – Leap Day Bugs!!
Yesterday I was fighting some errors on my current project, a SharePoint 2010 Home page that was working perfectly fine the day before suddenly was crashing now. After the initial rundown of "what did we change yesterday, what changed on the server, etc." to make sure there wasn’t some new bug that we accidentally introduced to the Dev environment I dug into the trusty SharePoint ULS LOGS directory in the 14 root and found this:
SharePoint wish List









