Customize Olap By Amo

28
Customize Project Server 2010 Analysis Management Object Version: 1.0 Prepared by: Huynh Thi Bao Chau Date: 9/26/2011 Coastal Point Solutions

description

 

Transcript of Customize Olap By Amo

Page 1: Customize Olap By Amo

Customize Project Server 2010

Analysis Management Object

Version:

Prepared by:

Date:

Coastal Point Solutions

Page 2: Customize Olap By Amo

Table of ContentsRevision history...........................................................................................................................................4

1. Analysis Management Object (AMO)..................................................................................................5

1.1. What is AMO?..................................................................................................................................5

1.2. Architecture.....................................................................................................................................5

1.3. AMO OLAP classes...........................................................................................................................5

2. Programming AMO OLAP Basic Objects..............................................................................................7

2.1. Dimension Objects...........................................................................................................................7

Creating, Dropping, and Finding a Dimension.........................................................................................7

Processing a Dimension...........................................................................................................................8

2.2. Cube Objects....................................................................................................................................8

Creating, Dropping, and Finding a Cube..................................................................................................8

Processing a Cube....................................................................................................................................9

2.3. MeasureGroup Objects..................................................................................................................10

Creating, Dropping, and Finding a MeasureGroup................................................................................10

Processing a Measure Group.................................................................................................................11

2.4. Partition Objects............................................................................................................................12

Creating, Dropping, and Finding a Partition...........................................................................................12

Processing a Partition............................................................................................................................12

Merging Partitions.................................................................................................................................13

2.5. Aggregation Objects......................................................................................................................13

2.6. Summary........................................................................................................................................14

3. Customizing Analysis Services (AS) Cube using AMO in Project Server 2010.....................................15

3.1. The code........................................................................................................................................15

References.............................................................................................................................................15

Event Handler........................................................................................................................................15

Retrieving AS DB Connection Strings.....................................................................................................16

Analysis Services Cube Customization...................................................................................................16

3.2. Deployment...................................................................................................................................18

Register Event Handler..........................................................................................................................18

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 2 of 24

Page 3: Customize Olap By Amo

Deploy Custom Assembly......................................................................................................................19

Add Eventing Config Parameters...........................................................................................................20

3.3. Testing...........................................................................................................................................20

3.4. Debug............................................................................................................................................22

4. References.........................................................................................................................................22

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 3 of 24

Page 4: Customize Olap By Amo

Revision historyName Date Reason for changes VersionHuynh Thi Bao Chau

9/26/2011 Newly created 1.0

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 4 of 24

Page 5: Customize Olap By Amo

1. Analysis Management Object (AMO)1.1. What is AMO?- Analysis Management Objects (AMO) is the complete library of programmatically accessed

objects that enables an application to manage a running instance of Microsoft SQL Server Analysis Services.

- AMO is an administrative object model you can use to programmatically manage instances of SSAS. AMO resides in the Microsoft.AnalysisServices namespace. There are a total of 260 classes found in this object model.

- Like all other SSAS object models, AMO translates programmatic calls into XMLA (XML for Analysis Services) and sends the XMLA to the SSAS instance.

1.2. Architecture

1.3. AMO OLAP classesThe hierarchy of objects exposed through AMO

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 5 of 24

Page 6: Customize Olap By Amo

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 6 of 24

Page 7: Customize Olap By Amo

2. Programming AMO OLAP Basic Objects2.1. Dimension Objects

Creating, Dropping, and Finding a DimensionCreating a Dimension object is accomplished in four steps:

1. Create the dimension object and populate basic attributes. 2. Create the attributes that define the dimension.3. Create the hierarchies that the user will access to navigate the dimension.4. Update the server by using the Update method of the current dimension.

The following sample code creates the Product dimension for the AdventureWorks2008R2 Sample Databases.

static void CreateProductDimension(Database db, string datasourceName){ // Create the Product dimension Dimension dim = db.Dimensions.FindByName("Product"); if ( dim != null) { dim.Drop(); } dim = db.Dimensions.Add("Product"); dim.Type = DimensionType.Products; dim.UnknownMember = UnknownMemberBehavior.Hidden; dim.AttributeAllMemberName = "All Products"; dim.Source = new DataSourceViewBinding(datasourceName); dim.StorageMode = DimensionStorageMode.Molap;

#region Create attributes

DimensionAttribute attr;

attr = dim.Attributes.Add("Product Name"); attr.Usage = AttributeUsage.Key; attr.Type = AttributeType.Product; attr.OrderBy = OrderBy.Name; attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimProduct", "ProductKey")); attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimProduct", "EnglishProductName");

#endregion

#region Create hierarchies

Hierarchy hier;

hier = dim.Hierarchies.Add("Product Model Categories"); hier.AllMemberName = "All Products"; hier.Levels.Add("Category").SourceAttributeID = "Category";

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 7 of 24

Page 8: Customize Olap By Amo

hier.Levels.Add("Subcategory").SourceAttributeID = "Subcategory"; hier.Levels.Add("Model Name").SourceAttributeID = "Model Name"; #endregion

dim.Update();}

static DataItem CreateDataItem(DataSourceView dsv, string tableName, string columnName){ DataTable dataTable = ((DataSourceView)dsv).Schema.Tables[tableName]; DataColumn dataColumn = dataTable.Columns[columnName]; return new DataItem(tableName, columnName, OleDbTypeConverter.GetRestrictedOleDbType(dataColumn.DataType));}

Processing a DimensionProcessing a dimension is as simple as using the Process method of the Dimension object.

Processing a dimension can affect all cubes that use the dimension.

The following code does an incremental update in all dimensions of a supplied database:

static void UpdateAllDimensions(Database db){ foreach (Dimension dim in db.Dimensions) dim.Process(ProcessType.ProcessUpdate);}

2.2. Cube Objects

Creating, Dropping, and Finding a CubeManaging cubes is similar to managing dimensions. Creating a Cube object is accomplished in four steps:

1. Create the cube object and populate basic attributes.2. Add the dimensions of the cube3. Create the Measure Groups that the user will access to browse the data of the cube4. Update the server by using the Update option ExpandFull to make sure that all objects are fully

updated in the server

The following code sample creates the parts of the Adventure Works cube.

static void CreateAdventureWorksCube(Database db, string datasourceName) { // Create the Adventure Works cube Cube cube = db.Cubes.FindByName("Adventure Works"); if ( cube != null)

{

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 8 of 24

Page 9: Customize Olap By Amo

cube.Drop(); }

db.Cubes.Add("Adventure Works"); cube.DefaultMeasure = "[Reseller Sales Amount]"; cube.Source = new DataSourceViewBinding(datasourceName); cube.StorageMode = StorageMode.Molap;

#region Create cube dimensions

Dimension dim;

dim = db.Dimensions.GetByName("Date"); cube.Dimensions.Add(dim.ID, "Date", "Order Date Key - Dim Time"); cube.Dimensions.Add(dim.ID, "Ship Date",Ship Date Key - Dim Time"); cube.Dimensions.Add(dim.ID, "Delivery Date",”Delivery Date Key - Dim Time");

dim = db.Dimensions.GetByName("Customer"); cube.Dimensions.Add(dim.ID);

dim = db.Dimensions.GetByName("Reseller"); cube.Dimensions.Add(dim.ID); #endregion

#region Create measure groups

CreateSalesReasonsMeasureGroup(cube); CreateInternetSalesMeasureGroup(cube); CreateResellerSalesMeasureGroup(cube); CreateCustomersMeasureGroup(cube); CreateCurrencyRatesMeasureGroup(cube);

#endregion

cube.Update(UpdateOptions.ExpandFull); }

Processing a CubeProcessing a cube is as simple as using the Process method of the Cube object. Processing a cube also processes all measure groups in the cube, and all partitions in the measure group.

In a cube, partitions are the only objects that can be processed; for the purposes of processing, measure groups are only containers of partitions. The specified type of processing for the cube propagates to the partitions. Processing of cube and measure group internally is resolved to processing of dimensions and partitions.

foreach (Cube cube in db.Cubes){ cube.Process(ProcessType.ProcessFull);

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 9 of 24

Page 10: Customize Olap By Amo

}

2.3. MeasureGroup Objects

Creating, Dropping, and Finding a MeasureGroupManaging measure groups is similar to managing dimensions and cubes. Creating a MeasureGroup object is accomplished in the following steps:

1. Create the measure group object and populate the basic attributes2. Create the measure group, verify that the measure group does not exist. In the sample code that

follows, if the measure group exists, then the measure group is dropped and re-created.3. Add the dimensions of the measure group4. Dimensions are added to the current measure group dimensions collection from the parent

cube dimensions collection. As soon as the dimension is included in the measure group dimensions collection, a key column from the fact table can be mapped to the dimension so that the measure group can be browsed through the dimension.

5. Add the designed partitions of the measure group.6. Update the server by using the Update method of current measure group.

static void CreateInternetSalesMeasureGroup(Cube cube) { // Create the Internet Sales measure group Database db = cube.Parent; MeasureGroup mg = cube.MeasureGroups.FindByName("Internet Sales"); if ( mg != null)

{ mg.Drop();

} mg = cube.MeasureGroups.Add("Internet Sales"); mg.StorageMode = StorageMode.Molap; mg.ProcessingMode = ProcessingMode.LazyAggregations; mg.Type = MeasureGroupType.Sales;

#region Create measures

Measure meas;

meas = mg.Measures.Add("Internet Sales Amount"); meas.AggregateFunction = AggregationFunction.Sum; meas.FormatString = "Currency"; meas.Source = CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "SalesAmount");

meas = mg.Measures.Add("Internet Unit Price"); meas.AggregateFunction = AggregationFunction.Sum; meas.FormatString = "Currency"; meas.Visible = false;

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 10 of 24

Page 11: Customize Olap By Amo

meas.Source = CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "UnitPrice");

#endregion

#region Create measure group dimensions

CubeDimension cubeDim; RegularMeasureGroupDimension regMgDim; ManyToManyMeasureGroupDimension mmMgDim; MeasureGroupAttribute mgAttr;

// Mapping dimension and key column from fact table // > select dimension and add it to the measure group cubeDim = cube.Dimensions.GetByName("Date"); regMgDim = new RegularMeasureGroupDimension(cubeDim.ID); mg.Dimensions.Add(regMgDim);

// > add key column from dimension and map it with // the surrogate key in the fact table mgAttr = regMgDim.Attributes.Add(cubeDim.Dimension.Attributes.GetByName("Date").ID); // this is dimension key column mgAttr.Type = MeasureGroupAttributeType.Granularity; mgAttr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "OrderDateKey")); // this surrogate key in fact table cubeDim = cube.Dimensions.GetByName("Product"); regMgDim = new RegularMeasureGroupDimension(cubeDim.ID); mg.Dimensions.Add(regMgDim); mgAttr = regMgDim.Attributes.Add(cubeDim.Dimension.Attributes.GetByName("Product Name").ID); mgAttr.Type = MeasureGroupAttributeType.Granularity; mgAttr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "ProductKey"));

#endregion

#region Create partitions

CreateInternetSalesMeasureGroupPartitions( mg)

#endregion }

Processing a Measure GroupProcessing a measure group is as simple as using the Process method of the MeasureGroup object. Processing a measure group will process all partitions that belong to the measure group. Processing a measure group internally is resolved to processing dimensions and partitions.

static void FullProcessAllMeasureGroups(Cube cube)

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 11 of 24

Page 12: Customize Olap By Amo

{ foreach (MeasureGroup mg in cube.MeasureGroups) mg.Process(ProcessType.ProcessFull); }

2.4. Partition Objects

Creating, Dropping, and Finding a PartitionPartitions are simple objects that can be created in two steps.

1. Create the partition object and populate the basic attributes.2. Update the server by using the Update method of the current partition.

The following code sample creates partitions for the 'InternetSales' measure group.

static void CreateInternetSalesMeasureGroupPartitions(MeasureGroup mg) { Partition part; part = mg.Partitions.FindByName("Internet_Sales_184"); if ( part != null)

{ part.Drop();

} part = mg.Partitions.Add("Internet_Sales_184"); part.StorageMode = StorageMode.Molap; part.Source = new QueryBinding(db.DataSources[0].ID, "SELECT * FROM [dbo].[FactInternetSales] WHERE OrderDateKey <= '184'"); part.Slice = "[Date].[Calendar Year].&[2001]"; part.Annotations.Add("LastOrderDateKey", "184");

part = mg.Partitions.FindByName("Internet_Sales_549"); if ( part != null)

{ part.Drop();

} part = mg.Partitions.Add("Internet_Sales_549"); part.StorageMode = StorageMode.Molap; part.Source = new QueryBinding(db.DataSources[0].ID, "SELECT * FROM [dbo].[FactInternetSales] WHERE OrderDateKey > '184' AND OrderDateKey <= '549'"); part.Slice = "[Date].[Calendar Year].&[2002]"; part.Annotations.Add("LastOrderDateKey", "549"); }

Processing a PartitionProcessing a partition is as simple as using the Process method of the Partition object.

static void FullProcessAllPartitions(MeasureGroup mg) { foreach (Partition part in mg.Partitions)

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 12 of 24

Page 13: Customize Olap By Amo

part.Process(ProcessType.ProcessFull); }

Merging PartitionsMerging partitions means performing any operation that results in two or more partitions becoming one partition.

Partitions can be merged only if they meet all the following criteria:

- Partitions are in the same measure group.- Partitions are stored in the same mode (MOLAP, HOLAP, and ROLAP).- Partitions reside on the same server; remote partitions can be merged if on the same server.

static void MergeAllPartitions(MeasureGroup mg){ if (mg.Partitions.Count > 1) { Partition[] partArray = new Partition[mg.Partitions.Count - 1]; for (int i = 1; i < mg.Partitions.Count; i++) partArray[i - 1] = mg.Partitions[i]; mg.Partitions[0].Merge(partArray); //To have last changes in the server reflected in AMO mg.Refresh(); }

2.5. Aggregation ObjectsAggregations can easily be created and assigned to measure groups or to partitions by using the DesignAggregations method from the AggregationDesign object.

static public String DesignAggregationsOnPartitions(MeasureGroup mg, double optimizationWanted, double maxStorageBytes) { double optimization = 0; double storage = 0; long aggCount = 0; bool finished = false; AggregationDesign ad = null; String aggDesignName; String AggregationsDesigned = "";

aggDesignName = mg.AggregationPrefix + "_" + mg.Name; ad = mg.AggregationDesigns.Add(); ad.Name = aggDesignName; ad.InitializeDesign(); while ((!finished) && (optimization < optimizationWanted) && (storage < maxStorageBytes)) {

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 13 of 24

Page 14: Customize Olap By Amo

ad.DesignAggregations(out optimization, out storage, out aggCount, out finished); } ad.FinalizeDesign();

foreach (Partition part in mg.Partitions) { part.AggregationDesignID = ad.ID; AggregationsDesigned += aggDesignName + " = " + aggCount.ToString() + " aggregations designed\r\n\tOptimization: " + optimization.ToString() + "/" + optimizationWanted.ToString() + "\n\r\tStorage: " + storage.ToString() + "/" + maxStorageBytes.ToString() + " ]\n\r"; } return AggregationsDesigned; }

2.6. SummaryManaging Objects AMO (C#)

Connecting to the Server amoServer.Connect("SS2005_Server");Creating database amoDB = amoServer.Databases.Add("NewDb");

amoDB.Update();

Create cube amoCube = amoDB.Cubes.Add("NewCube");amoCube.Update();

Create measure //in SQL Server, Analysis Services cubes can have more than 1 measure group. A measure group was required before adding the measure

amoMG = amoCube.MeasureGroups.Add("NewMeasureGroup");amoMeas = amoMG.Measures.Add("NewMeasure");amoMG.Update();

Removing database //being amoDB a database object//the database pointed by amoDB is dropped from system

amoDB.Drop();

Removing cube //being amoCube a cube object//the cube pointed by amoCube is dropped from system

amoCube.Drop();

Changing Object //Start cube definition

//Set Description for new cube

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 14 of 24

Page 15: Customize Olap By Amo

amoCube.Description = "simplified sales cube";

//Provide the data source for the cube.amoCube.Source = new DataSourceViewBinding("FoodMart");

//Update cube to save changesamoCube.Update();

Processing Objects //Default processing for all objects in a databasedsoDB.Process( ProcessType.ProcessDefault);

//Full processing a cubeamoCube.Process( ProcessType.ProcessFull);

3. Customizing Analysis Services (AS) Cube using AMO in Project Server 20103.1. The code

ReferencesTo be able to override an EPM 2010 Event Handler and do AMO customization you will have to add the following references to the C# Class Library solution:

- C:\Program Files\Microsoft SQL Server\90\SDK\Assemblies\Microsoft.AnalysisServices.dll- C:\Program Files\Microsoft Office Servers\12.0\Bin\

Microsoft.Office.Project.Server.Events.Receivers.dll- C:\Program Files\Microsoft Office Servers\14.0\Bin\Microsoft.Office.Project.Server.Library.dll

Event HandlerThe CubeProcecessedEvent is overridden to launch our Analysis Services Cube customization once the standard EPM 2010 cube has been built:

// Override CBS event to call custom AMO code public class CubeProcessedEvent : CubeAdminEventReceiver { #region Public Methods

public override void OnCubeProcessed(PSContextInfo contextInfo, CubeAdminPostCubeProcessEventArgs e) { base.OnCubeProcessed(contextInfo, e);

// Process Analysis Services customization ProcessCubeCustomisation(e.DbName);

}

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 15 of 24

Page 16: Customize Olap By Amo

Retrieving AS DB Connection StringsThe CONFIG file is located under: C:\Program Files\Microsoft Office Servers\14.0\Bin

// --------------------------------------------// STEP 0: Retrieve Analysis Services server configuration from// Microsoft.Office.Project.Server.Eventing.exe.config// --------------------------------------------string connectionString = ConfigurationManager.AppSettings["ASConnectionString"];

Analysis Services Cube CustomizationThis is the main method doing all the Analysis Services customization (using AMO):

private void ProcessCubeCustomisation(string databaseName) {Stopwatch timeToProcess = new Stopwatch();timeToProcess.Start();bool success = false;string msg = string.Empty;

try{ // -------------------------------------------- // STEP 0: Retrieve Analysis Services server configuration from // Microsoft.Office.Project.Server.Eventing.exe.config // -------------------------------------------- string connectionString = ConfigurationManager.AppSettings["ASConnectionString"]; string databaseName = ConfigurationManager.AppSettings["ASDatabaseName"];

// -------------------------------------------- // STEP 1: Connect to Analysis Services server. // -------------------------------------------- Server asServer = new Server(); asServer.Connect(connectionString);

// -------------------------------------------- // STEP 2: Locate the necessary OLAP objects. // -------------------------------------------- Database p12Database = asServer.Databases.GetByName(databaseName); // this throws exception if the database is not found Cube mspPortfolioAnalyzer = p12Database.Cubes.GetByName("MSP_Portfolio_Analyzer"); Dimension taskListDimension = p12Database.Dimensions.GetByName("Task List"); // this throws exception if the dimension is not found

// -------------------------------------------- // STEP 3: Perform OLAP customisation // -------------------------------------------- DimensionAttribute tnDimAtt = taskListDimension.Attributes.Add("Task Name"); tnDimAtt.Usage = AttributeUsage.Regular; tnDimAtt.Type = AttributeType.Regular; tnDimAtt.OrderBy = OrderBy.Name;

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 16 of 24

Page 17: Customize Olap By Amo

tnDimAtt.KeyColumns.Add(CreateDataItem(p12Database.DataSourceViews[0], "MSP_EpmTask_OlapView_Dimension", "TaskName")); tnDimAtt.NameColumn = CreateDataItem(p12Database.DataSourceViews[0], "MSP_EpmTask_OlapView_Dimension", "TaskName");

// Create Task Name Hierarchy Hierarchy tnHierarchy = taskListDimension.Hierarchies.Add("TaskNameHierarchy"); DimensionAttribute tlAttribute = taskListDimension.Attributes.GetByName("Task List attribute"); tlAttribute.AttributeRelationships.Add("Task Name"); tnHierarchy.Levels.Add(tnDimAtt.Name).SourceAttributeID = tnDimAtt.Name; tnHierarchy.Levels.Add(tlAttribute.Name).SourceAttributeID = tlAttribute.Name;

ValidationErrorCollection errorCol = new ValidationErrorCollection(); taskListDimension.Validate(errorCol, true);

// -------------------------------------------- // STEP 4: Process updates // -------------------------------------------- // Process dimension update p12Database.Update(UpdateOptions.ExpandFull); p12Database.Process(ProcessType.ProcessFull);

success = true;}catch (Exception e){ msg = "FAILED to process AS customisation, exception: " + e.Message;}

timeToProcess.Stop();if (success) WriteEvent("SUCCESSFULY processed AS customisation, Time= " + timeToProcess.Elapsed.ToString(), EventLogEntryType.Information, 9999);else WriteEvent(msg + " , Time= " + timeToProcess.Elapsed.ToString(), EventLogEntryType.Error, 9999); }

private DataItem CreateDataItem(DataSourceView dsv, string tableName, string columnName) { string selectedTableName = tableName; for (int i = 0; i < ((DataSourceView)dsv).Schema.Tables.Count; i++ ) { if (((DataSourceView)dsv).Schema.Tables[i].TableName.Contains(tableName)) { selectedTableName = ((DataSourceView)dsv).Schema.Tables[i].TableName; break; } } DataTable dataTable = ((DataSourceView)dsv).Schema.Tables[selectedTableName]; DataColumn dataColumn = dataTable.Columns[columnName]; return new DataItem(selectedTableName, columnName, OleDbTypeConverter.GetRestrictedOleDbType(dataColumn.DataType)); }

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 17 of 24

Page 18: Customize Olap By Amo

3.2. Deployment The procedure to deploy custom Event Handler (calling custom AMO code) is as follow:

Register Event Handler

1. Connect to the PWA server and go to Server Settings2. Select Operational Policies -> Server-Side Event Handler Configuration3. Select Cube Admin -> Cube Processed

4. Enter the following information and click Save:

Name Custom Task Name Hierarchy

Description Custom AMO code that aggregates tasks by name

Assembly Name CoastalPoint.CustomProjectServer.AMOEvent, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=9af84715c1210e08

Classe Name CoastalPoint.CustomProjectServer.AMOEvent.CubeProcessedEvent

Order 1

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 18 of 24

Page 19: Customize Olap By Amo

Once the assembly has been deployed it should appear as shown below (takes a few minutes to take effect):

Deploy Custom Assembly

5. Copy compiled assembly AMOEvent.dll from proper BIN directory to C:\WINDOWS\assembly (Drag & Drop)

6. Assembly should now appear in the folder as shown below:

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 19 of 24

Page 20: Customize Olap By Amo

Add Eventing Config Parameters

7. Copy the EPM Eventing config file located under C:\Program Files\Microsoft Office Servers\12.0\Bin\Microsoft.Office.Project.Server.Eventing.exe.config to have a backup and open the file using an XML editor

8. Add the following parameter: ASConnectionString<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <probing privatePath="ProjectServerEventHandlers"/> </assemblyBinding> </runtime><appSettings>

<add key="ASConnectionString" value="CHRISFIE03\SQL" /></appSettings>

</configuration>

3.3. TestingFirst you will have to the build the cube with the newly deployed customization.

The CBS (Cube Building Process) will look like this:

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 20 of 24

Page 21: Customize Olap By Amo

Ensure that the newly added hierarchy has been added to the cube using Visual Studio:

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 21 of 24

Page 22: Customize Olap By Amo

Specifically:

3.4. Debug - Deploy project- Go to Service, restart 2 services: Microsoft Project Server Events Service 2010 and Microsoft

Project Server Queue Service 2010- Attach process : Microsoft.Office.Project.Server.Eventing.exe- Go to PWA -> Server Settings -> OLAP Database Management, choose a database and click Build

Now button.

4. References

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 22 of 24

Page 23: Customize Olap By Amo

http://msdn.microsoft.com/en-us/library/ms124924.aspx

http://ssas-wiki.com/w/Articles#Analysis_Management_Objects_.28AMO.29

http://blogs.msdn.com/b/chrisfie/archive/2007/08/06/customizing-analysis-services-cube-using-analysis-management-objects-amo.aspx

The information contained herein is confidential and proprietary and should not be disclosed, copied or duplicated in any manner without written permission of Coastal Point Solutions.

Document Version Page 23 of 23