-->
Showing posts with label Dhaval Shah Sharepoint Blogs. Show all posts
Showing posts with label Dhaval Shah Sharepoint Blogs. Show all posts

Friday, 13 July 2012

Application Server job failed for service instance

All of a sudden, my FAST search server started bogging me this error several times.


Application Server job failed for service instance Microsoft.Office.Server.Search.Administration.SearchServiceInstance
Reason: An update conflict has occurred, and you must re-try this action



When I checked the ULS Logs it showed me the Trace below 



Application Server Administration job failed for service instance Microsoft.Office.Server.Search.Administration.SearchServiceInstance (21e4447f-bac6-4a29-82db-165e074ac5db).
Reason: An update conflict has occurred, and you must re-try this action. The object SearchDataAccessServiceInstance was updated by domain\user, in the OWSTIMER (5040) process, on machine (server name).  View the tracing log for more information about the conflict.
Technical Support Details: 
Microsoft.SharePoint.Administration.SPUpdatedConcurrencyException: An update conflict has occurred, and you must re-try this action. The object SearchDataAccessServiceInstance was updated by domain\user, in the OWSTIMER (5040) process, on machine (server name).  View the tracing log for more information about the conflict. 
   at Microsoft.Office.Server.Search.Administration.SearchServiceInstance.Synchronize()
   at Microsoft.Office.Server.Administration.ApplicationServerJob.ProvisionLocalSharedServiceInstances(Boolean isAdministrationServiceJob)



Resetting the index and Recreating the SSA didn't work either !Luckily after a lot of troubleshooting and looking around I found a fix ! Thanks to this guy !

OK , So resolution 

Resolution:
The file system cache on all FE’s (in my case, this was just one server) on which the timer service is running needs to be cleared.
Below is the step by step provided by Microsoft in this KB Article for doing this:
  1. Stop the Windows SharePoint Services Timer service (Found in Windows Services)
  2. Navigate to the cache folder
    In Windows Server 2008, the configuration cache is in the following location:
    Drive:\ProgramData\Microsoft\SharePoint\Config
    In Windows Server 2003, the configuration cache is in the following location:
    Drive:\Documents and Settings\All Users\Application Data\Microsoft\SharePoint\Config
    Locate the folder that has the file "Cache.ini"
    (Note: The Application Data folder may be hidden. To view the hidden folder, change the folder options as required)
  3. Back up the Cache.ini file.
  4. Delete all the XML configuration files in the GUID folder. Do this so that you can verify that the GUID folder is replaced by new XML configuration files when the cache is rebuilt.
  5. Note When you empty the configuration cache in the GUID folder, make sure that you do not delete the GUID folder and the Cache.ini file that is located in the GUID folder.
  6. Double-click the Cache.ini file.
  7. On the Edit menu, click Select All. On the Edit menu, click Delete. Type 1, and then click Save on the File menu. On the File menu, click Exit.
  8. Start the Windows SharePoint Services Timer service
  9. Note The file system cache is re-created after you perform this procedure. Make sure that you perform this procedure on all servers in the server farm.
  10. Make sure that the Cache.ini file in the GUID folder now contains its previous value. For example, make sure that the value of the Cache.ini file is not 1.




I Hope this article was informative. Happy Sharepointing !

Please do Share/Like/Comment if this article was helpful.



Unable To Resolve Content Distributor

I have been getting the error 'Unable to Resolve Content Distributor' when I run the Sharepoint product configuration wizard. When I googled most of the places it is given to change the content distributor in your search service application port number to 13390 instead of 13391. But my SSA was working perfectly with the 13391, so it was not an issue.


Follow the below steps and make sure your configuration is appropriate.

  1. Ping-SPEnterpriseSearchContentService -HostName hostname:portnumber
     This will display the certificates used by the service. Make sure the connectionsuccess status for the FASTSearchCert is 'True'. If it is set to false you need to install it again using 
    SecureFASTSearchConnector.ps1 script. Refer my post here.
  2. create and re-install the MOSS_STS.cer again. Execute the below commands in sharepoint management shell.

    $stsCert = (Get-SPSecurityTokenServiceConfig).LocalLoginProvider.SigningCertificate
    $stsCert.Export("cert") | Set-Content -encoding byte MOSS_STS.cer


    This will generate the certificate in the folder where you executed the command. Install this certificate using the  InstallSTSCertificateForClaims.ps1. It is located under "%FASTSearch%\Installer\scripts" folder

    InstallSTSCertificateForClaims.ps1 -certPath "certificate_path\MOSS_STS.cer"
This steps resolved my issue !

I Hope this article was informative. Happy Sharepointing !

Please do Share/Like/Comment if this article was helpful.

Monday, 21 May 2012

Sharepoint 2010 Client Object Model - Part 2

In my previous post we discussed about the basic's of the Client Object Model in Sharepoint 2010 and it's architecture.


As we discussed COM can be implemented using 3 client API's viz
  1. .NET managed application (Console application/Windows Forms Application) 
  2. Silverlight 2.0 application
  3. ECMAScript (JavaScript, JScript)

This Article we will discuss it with the use of the .Net Managed Application


Create a console application with Microsoft .Net Framework 3.5 and use the following code snippet in the Main File
Note : You will be required to add reference to the Sharepoint Client Assemblies located under C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI

  • Microsoft.SharePoint.Client.dll
  • Microsoft.SharePoint.Client.Runtime.dll

static void Main(string[] args)
        {
            var _ctx = new ClientContext("<sitecolleciton_url>");
            var _web = _ctx.Web;
            var _lists = _web.Lists;

            _ctx.Load(_lists, c => c.Include(l => l.Title, l => l.Description)
                  .Where(l => l.Hidden == false)
                );

            // Call to the Load method does not actually load anything.
            // Instead, it informs the client object model that when the
            // application calls the ExecuteQuery method, you want to load
            // the property values of the siteCollection object.
            _ctx.ExecuteQuery();

            foreach (var list in _lists)
            {
                Console.WriteLine(list.Title + " *** " + ((list.Description.Length > 0) ? list.Description.Substring(0, 25) + "..." : String.Empty));
            }
            Console.ReadLine();
        }



ClientContext : ClientContext object instantiates the context object for a specific site collection. It serves as the main entry point for accessing the client object model.
Load : This method is called to retrieve the properties of a specified client object, such as the ListCollection collection. The properties are stored in the client object. Request call to the sharepoint is not made yet during this call, it will just store the properties that has to be retreived.
ExecuteQuery : The call to the ExecuteQuery method causes the SharePoint Foundation 2010 managed client object model to send the request to the server. There is no network traffic until the application calls the ExecuteQuery method.

Note : To optimize data retrieval, the Client OM queue all requests to the SharePoint server till an invocation to the ExecuteQuery is made. So no data will be available from the server till the ExecuteQuery method is invoked. If you want to use a property that you are not asked to load in the ClientContext.Load method, you’ll get PropertyOrFieldNotInitializedException is thrown.

In our other example we will use the LoadQuery method

static void Main(string[] args)
        {
            var _ctx = new ClientContext(" <sitecolleciton_url> ");
            var _web = _ctx.Web;
            var _lists = _web.Lists;

             var _query = from list in _lists select list;
            // The LoadQuery method has different semantics than the Load method.
            // Whereas the Load method populates the client object 
            // (or client object collection) with data from the server, the LoadQuery                                                   
            // method populates and returns a new collection.
            // This means that you can query the same object collection multiple times
            // and keep separate result sets for each query.
            IEnumerable<List> myLists = _ctx.LoadQuery(_query);
            _ctx.ExecuteQuery();

            foreach (var list in myLists)
            {
                Console.WriteLine(list.Title + " ***** " + list.Description);
            } 
            Console.ReadLine();
        }


 LoadQuery : The LoadQuery method is similar in functionality to the Load method, except that LoadQuery method populates and returns a new collection while Load method populates the client object. This means that you can query the same object collection multiple times and keep separate result sets for each query. Additionally you can filter the returned result set.

Below example depicts how to create a list, In this case We have created the document library "My Docs"

static void Main(string[] args)
        {
            var _ctx = new ClientContext(" <sitecolleciton_url> ");
            var _web = _ctx.Web;
            var _lists = _web.Lists;

            //Create a document library
            ListCreationInformation listCreationInfo = new ListCreationInformation();
            listCreationInfo.Title = "My Docs";
            listCreationInfo.TemplateType = (int)ListTemplateType.DocumentLibrary;

            List oList = _web.Lists.Add(listCreationInfo);

            _ctx.ExecuteQuery();

        }


Same way we can update the properties of the lists, See the code-snippet below

static void Main(string[] args)
        {
            var _ctx = new ClientContext(" <sitecolleciton_url> ");
            var _web = _ctx.Web;
            var _lists = _web.Lists;

            //Update the list information
            List oList = _web.Lists.GetByTitle("My Docs");

            oList.Description = "My Document reporsitory";

            oList.Update();

            _ctx.ExecuteQuery();

        }



In our subsequent articles we will describe how to implement each of the COM using different client.

I Hope this article was informative. Happy Sharepointing !

Please do Share/Like/Comment if this article was helpful.

Tuesday, 8 May 2012

Sharepoint 2010 Client Object Model - Part 1

Last week one of my colleague took a session for all of us to explain the Client Object Model in Sharepoint 2010, so i thought to share the knowledge via this blog article.


What is Client Object Model (COM)
Client Object Model (Client OM) is a unified model which can be used by developers to access the server. The Client OM can be accessed via web services, via a client (JavaScript) API, and via REST. Microsoft SharePoint 2010 introduces three new client APIs that allow you to interact with SharePoint sites from script that executes in the browser, from code that executes in a .NET managed application, or from code that executes in a Microsoft Silverlight 2.0 application.


Key Points one should know about the COM:
  1. There are limitations to what can be done client side compared to server side, say for example you cannot access the FARM level properties, you can get/set only the properties at the web application level.
  2. we cannot elevate the privilege in COM as we can do in server object model.
  3. No SharePoint installation is required in the development machine.Only  the Client DLL's are required.
  4. No Compilation required as required on the server side, NO IISRESET required.
  5. Path to get DLL's: C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI


The following table shows the equivalent objects that the new APIs provide for common SharePoint Foundation 2010 server objects.

Server Object Model .Net Managed & Silverlight JavaScript
SPContext ClientContext SP.ClientContext
SPSite Site SP.Site
SPWeb Web SP.Web
SPSite.Title Site.Title SP.Site.get_title() & SP.Site.set_title()

Client Object Model Mechanics
Below mentioned diagram explains the architecture of the Client Object Model in Sharepoint 2010
Image Reference is here
  • Client Object Model is a façade on top of WCF service.
  • Requests for the resources are batched using Load & LoadQuery methods.
  • Requests are executed using ExecuteQuery or ExecuteQueryAsync methods.
    • XML document with batched request information is sent to server.
    • JSON response with requested resources is sent back to the client.
In our subsequent articles we will describe how to implement each of the COM using different client.

I Hope this article was informative. Happy Sharepointing !


Please do Share/Like/Comment if this article was helpful.

Monday, 7 May 2012

Running Sharepoint Central Administration Site on more than one server in the Sharepoint Farm

Lately i was asked, if it's possible to run the SharePoint Central Administration if the application server hosting it is offline/dead. 
So yes, It's Possible !
Consider the following simple 3-Tier Sharepoint Architecture farm
Here are there are three servers
  1. SharePoint Database Server : This server contains the SQL server dedicated/Shared to the SharePoint 2010 Farm. It contains all the database for the Web Application/Service Applications residing in the SharePoint Farm.
  2. Application Server : This server contains the Central Administration Site hosted and all the other service applications running on it.
  3. Web-Front End Server : This server will act as the web-front end server. There can be more than 1 WFE server in a SharePoint Farm, where load balancer will balance the end-user request coming to the SharePoint farm to each of this servers.
So now at this point we have Central Administration site running on the application server. But what if the Application server is down ? Our site which has been hosted on the application server will be inactive and your sharepoint farm will be without Central Administration Site.

So in order to overcome this issue we can configure the central administration site for the farm on the Web-Front End server as well.

How to do that?

For this we need to configure the SharePoint 2010 on the WFE (In Case, you have already configured it, reconfigure again) using the SharePoint 2010 Products Configuration Wizard.

Initial setup will remain same, Follow the screenshot's specified below







Now 'Advanced Settings' comes into the picture, Click on it
Generally if we do not want to create separate Central administration we use the first option, But here as we want to create additional central administration  we will select the second option. Click on OK and Finish the wizard.


On Successful, completion of wizard it will open the central administration site of this server!



Monday, 16 April 2012

Sharepoint Page Request V/S ASP.Net Page Request


Before we compare life cycle of both the page request lets  first understand the asp.net application life cycle.


Stages of the ASP.NET application life cycle (IIS 7.0):
  1. Request is made for an application resource: When the integrated pipeline receives a request, the request passes through stages that are common to all requests. These stages are represented by the RequestNotification enumeration. All requests can be configured to take advantage of ASP.NET functionality, because that functionality is encapsulated in managed-code modules that have access to the request pipeline. For example, even though the .htm file-name extension is not explicitly mapped to ASP.NET, a request for an HTML page still invokes ASP.NET modules. This enables you to take advantage of ASP.NET authentication and authorization for all resources.
  2. The unified pipeline receives the first request for the application: When the unified pipeline receives the first request for any resource in an application, an instance of the ApplicationManager class is created, which is the application domain that the request is processed in. Application domains provide isolation between applications for global variables and enable each application to be unloaded separately. In the application domain, an instance of the HostingEnvironment class is created, which provides access to information about the application, such as the name of the folder where the application is stored. During the first request, top-level items in the application are compiled if required, which includes application code in the App_Code folder.
  3. Response objects are created for each request: After the application domain has been created and the HostingEnvironment object has been instantiated, application objects such as HttpContext, HttpRequest, and HttpResponse are created and initialized.



  4. An HttpApplication object is assigned to the request: After all application objects have been initialized, the application is started by creating an instance of the HttpApplication class. If the application has a Global.asax file, ASP.NET instead creates an instance of the Global.asax class that is derived from the HttpApplication class. It then uses the derived class to represent the application.
    Which ASP.NET modules are loaded (such as the SessionStateModule) depends on the managed-code modules that the application inherits from a parent application. It also depends on which modules are configured in the configuration section of the application's Web.config file. Modules are added or removed in the application's Web.config modules element in the system.webServer section.
  5. The request is processed by the HttpApplication pipeline: At this stage the request are processed and various events are called like ValidateRequest, URL Mapping, BeginRequest, AuthenticateRequest and so on. You can find more info over here. The events are useful for page developers who want to run code when key request pipeline events are raised. They are also useful if you are developing a custom module and you want the module to be invoked for all requests to the pipeline. Custom modules implement the IHttpModule interface. In Integrated mode in IIS 7.0, you must register event handlers in a module's Init method.

Stages of the Sharepoint Page Request

                The stages for the SharePoint page request are handled by the IIS in similar way. Except that there are custom handlers for the every sharepoint page request.

When you create a web application in sharepoint, WSS configures the IIS website by adding an IIS application map and creating several virtual directories. Windows SharePoint Services also copies a global.asax file and web.config file to the root directory of the hosting IIS Web site.

Because every request targeting a Web application is routed through aspnet_isapi.dll, the request gets fully initialized with ASP.NET context. Furthermore, its processing behavior can be controlled by using a custom HttpApplication object and adding configuration elements to the web.config file.

First, you can see that Windows SharePoint Services configures each Web application with a custom HttpApplication object by using the SPHttpApplication class. Note that this class is deployed in the Windows SharePoint Services system assembly Microsoft.SharePoint.dll.


In addition to including a custom HttpApplication object, the Windows SharePoint Services architecture uses a custom HttpHandler(SPHttpHandler) and a custom HttpModule(SPRequestModule). These two SharePoint-specific components are integrated into the HTTP Request Pipeline for a Web application using standard entries in the web.config file.


<configuration>
  <system.web>

    <httpHandlers>
      <remove verb="GET,HEAD,POST" path="*" />
      <add verb="GET,HEAD,POST" path="*"
          type="Microsoft.SharePoint.ApplicationRuntime.SPHttpHandler,..." />
    </httpHandlers>

    <httpModules>
      <clear />
      <add name="SPRequest
        type="Microsoft.SharePoint.ApplicationRuntime.SPRequestModule,..."/>
      <!-- other standard ASP.NET httpModules added back in -->
    </httpModules>

  </system.web>
</configuration>



ASP.NET 2.0 introduced a new pluggable component type known as a virtual path provider. The idea behind a virtual path provider is that it abstracts the details of where page files are stored away from the ASP.NET runtime. By creating a custom virtual path provider, a developer can write a custom component that retrieves ASP.NET file types, such as .aspx and .master files, from a remote location, such as a Microsoft SQL Server database.

The Windows SharePoint Services team created a virtual path provider named SPVirtualPathProvider that is integrated into every Web application. The SPVirtualPathProvider class is integrated into the ASP.NET request handling infrastructure by the SPRequestModule. More specifically, the SPRequestModule component contains code to register the SPVirtualPathProvider class with the ASP.NET Framework as it does its work to initialize a Web application.
I Hope you liked the article. Please do provide your feedback in the comment box.

Thank you ! Happy Sharepointing !

Tuesday, 27 March 2012

Add Rating Stars to the Search Results

I Hope you found my previous article on Encoding and Decoding Refiner Values useful. In this article I will Explain to how to Add Rating Stars to the search results. Please let me know if you find any issues while implementing it.

Create a Custom List and Enable Rating on it

We will start with creating the list with some dummy columns and insert some data in it. I have created a 'Employee List' whose structure looks something like this

Now we need to enable the rating to the list. Click on the list settings from the ribbon under the 'List Tools' Group and 'List' tab
Now click on the 'Rating Settings' link under the 'General Settings' category.
Select 'Yes' under 'Allow items in this list to be rated?' and click 'Ok'.

This has successfully enabled ratings on the list and added following two columns required for rating to work.

Rating (0-5)   Rating (0-5)  
Number of Ratings   Number of Ratings 

If you go back to the list it would have added the Rating Column to the list.


Rate some Entries in the List and Run the Services for Rating

Now add rating to these entries. It wont be reflected immediately on the list, it will get updated once 'User Profile Service Application - Social Data Maintenance Job' and  
'User Profile Service Application - Social Rating Synchronization Job' jobs are executed.


This jobs are scheduled to run every hour (By default) by the sharepoint timer services. However we can change the frequency of the this jobs

Go to Central Administration -> Monitoring -> Timer Jobs -> Review job definitions

Scroll down to locate the above services


Click on each of the job and schedule it to run for every 1 min (Just so that we don't have to wait for our ratings to get updated, in normal scenario running every 

one hour is just fine !)

Once this jobs are executed successfully, the ratings that you entered previously would have started reflecting.


Start the Full Crawl of the site to Create Crawl Property


Now once we have to prepare our FAST search server to include the ratings in our search indexing.

So go to the crawled property categories and select 'Sharepoint' category. Now search for 'rating'

It should return following to crawled properties

ows_averagerating(Decimal)
ows_ratingcount(Integer)


If it does not return the above two crawled properties, You need to start full crawl of the site where your list is located.
Once the crawl is successfull, sharepoint will automatically create the above crawled properties

Create Managed Property for the Ratings


As we have the crawled property created we can create a managed property for each of them and map it to crawled property.

So you need to create following two managed property
a. Rating
b. RatingCount

Below are the details of the managed property that will help you to create a managed property.



Start the full crawl of the Site

After creating the managed property we need to full crawl the site 'AGAIN'. Yes, When we earlier crawled the site it just recognised that two more fields are available for crawling. But managed properties were not mapped so it didnt knew where to index the data.

so start the full crawl of the site, leave it as it is and proceed to the next step.

Modify Core Result Webpart and it's XSLT

Now we need to modify the search webpart of our site to display the rating stars in our search.

So go to your results.aspx and then edit the page. Now edit your core results webpart.

Under coreresultswebpart properties->Core Result -> Display Properties -> Fethced Properties
A. Include the following lines before the </Column> tag

<Column Name="Rating"/>
<Column Name="RatingCount"/>

B. Open the XSL Editor of the webpart by clicking on 'XSL Editor' button

Add the below lines of code after the Div tag of '<div class="srch-Title2">'

  <div class="srch-Description">
    <xsl:if test="rating &gt; 0">
      <b>
        <xsl:call-template name="DisplayRating">
          <xsl:with-param name="theRating" select="rating" />
          <xsl:with-param name="theRatingCount" select="ratingcount" />
        </xsl:call-template>
      </b>
      <br />
    </xsl:if>
  </div>

C. Copy the following code before the </xsl:stylesheet> tag

<xsl:template name="DisplayRating">
  <xsl:param name="theRating"/>
  <xsl:param name="theRatingCount"/>
  <xsl:if test="$theRating > 0">
    <div style="display: inline-block; padding-left: 8px;">
      <div>
        <xsl:variable name="tempTitle" select="concat($theRating, ' Stars (')"/>
        <xsl:variable name="tempTitle2" select="concat($theRatingCount, ' Ratings)')"/>
        <xsl:variable name="ratingTitle" select="concat($tempTitle, $tempTitle2)"/>

        <xsl:attribute name="title">
          <xsl:value-of select="$ratingTitle"/>
        </xsl:attribute>
        <xsl:choose>
          <xsl:when test="round($theRating) = 0 and $theRating &gt; 0">
            <xsl:attribute name="style">background-image:url(/_layouts/images/Ratings.png);cursor:default;height:16px;margin:0px;background-repeat:no-repeat;background-position:-368px 0px;width:16px;</xsl:attribute>
          </xsl:when>
          <xsl:when test="round($theRating) = 1 and round($theRating) &lt;= $theRating">
            <xsl:attribute name="style">background-image:url(/_layouts/images/Ratings.png);cursor:default;height:16px;margin:0px;background-repeat:no-repeat;background-position:-352px 0px;width:16px;</xsl:attribute>
          </xsl:when>
          <xsl:when test="round($theRating) = 2 and round($theRating) &gt; $theRating">
            <xsl:attribute name="style">background-image:url(/_layouts/images/Ratings.png);cursor:default;height:16px;margin:0px;background-repeat:no-repeat;background-position:-352px 0px;width:32px;</xsl:attribute>
          </xsl:when>
          <xsl:when test="round($theRating) = 2 and round($theRating) &lt;= $theRating">
            <xsl:attribute name="style">background-image:url(/_layouts/images/Ratings.png);cursor:default;height:16px;margin:0px;background-repeat:no-repeat;background-position:-336px 0px;width:32px;</xsl:attribute>
          </xsl:when>
          <xsl:when test="round($theRating) = 3 and round($theRating) &gt; $theRating">
            <xsl:attribute name="style">background-image:url(/_layouts/images/Ratings.png);cursor:default;height:16px;margin:0px;background-repeat:no-repeat;background-position:-336px 0px;width:48px;</xsl:attribute>
          </xsl:when>
          <xsl:when test="round($theRating) = 3 and round($theRating) &lt;= $theRating">
            <xsl:attribute name="style">background-image:url(/_layouts/images/Ratings.png);cursor:default;height:16px;margin:0px;background-repeat:no-repeat;background-position:-320px 0px;width:48px;</xsl:attribute>
          </xsl:when>
          <xsl:when test="round($theRating) = 4 and round($theRating) &gt; $theRating">
            <xsl:attribute name="style">background-image:url(/_layouts/images/Ratings.png);cursor:default;height:16px;margin:0px;background-repeat:no-repeat;background-position:-320px 0px;width:62px;</xsl:attribute>
          </xsl:when>
          <xsl:when test="round($theRating) = 4 and round($theRating) &lt;= $theRating">
            <xsl:attribute name="style">background-image:url(/_layouts/images/Ratings.png);cursor:default;height:16px;margin:0px;background-repeat:no-repeat;background-position:-304px 0px;width:64px;</xsl:attribute>
          </xsl:when>
          <xsl:when test="round($theRating) = 5 and round($theRating) &gt; $theRating">
            <xsl:attribute name="style">background-image:url(/_layouts/images/Ratings.png);cursor:default;height:16px;margin:0px;background-repeat:no-repeat;background-position:-304px 0px;width:80px;</xsl:attribute>
          </xsl:when>
          <xsl:when test="round($theRating) = 5">
            <xsl:attribute name="style">background-image:url(/_layouts/images/Ratings.png);cursor:default;height:16px;margin:0px;background-repeat:no-repeat;background-position:-160px 0px;width:80px;</xsl:attribute>
          </xsl:when>
        </xsl:choose>
      </div>
    </div>
  </xsl:if>
</xsl:template>




Click 'Ok' and save the page.

Search Results

You are ready to search for the results now ! My search page something like this 



So this brings to end of this post.

Thank you.. Have a nice day !
Happy Sharepointing !