{"id":46826,"date":"2025-02-21T00:00:00","date_gmt":"2025-02-21T08:00:00","guid":{"rendered":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/blog\/griddb-with-salesforce-integration\/"},"modified":"2025-11-13T12:57:15","modified_gmt":"2025-11-13T20:57:15","slug":"griddb-with-salesforce-integration","status":"publish","type":"post","link":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/","title":{"rendered":"GridDB with Salesforce Integration"},"content":{"rendered":"<h2><strong>Introduction<\/strong><\/h2>\n<p>In today&#8217;s competitive landscape, efficient customer support is essential for retaining customers and driving business success. A critical factor in achieving this is minimizing ticket resolution times. By analyzing and optimizing these times, organizations can identify bottlenecks, improve support workflows, and enhance overall customer satisfaction<\/p>\n<p>Salesforce, a widely used CRM platform, provides a foundation for managing customer interactions. However, to gain deeper insights into ticket resolution times and identify areas for improvement, organizations can leverage the power of GridDB. This high-performance time series database is designed to handle large volumes of time-sensitive data efficiently.<\/p>\n<p>This blog will walk you through creating a dashboard that integrates Salesforce CRM service ticket data with GridDB for time series analysis and visualization of average ticket resolution times. We&#8217;ll cover how to extract data using RESTful APIs with Spring Boot, store it in GridDB, query the data for valuable insights, and ultimately visualize the results.<\/p>\n<h2>Setting Up GridDB Cluster and Spring Boot Integration: For Real-Time Monitoring<\/h2>\n<p>To effectively perform time series analysis on customer support ticket resolution times, the first step is to set up a GridDB cluster and integrate it with your Spring Boot application.<\/p>\n<ul>\n<li><strong>Setting up GridDB Cluster<\/strong><\/li>\n<\/ul>\n<p>GridDB provides flexible options to meet different requirements. For development, a single-node cluster on your local machine may be sufficient. However, in production, distributed clusters across multiple machines are typically preferred for improved fault tolerance and scalability. For detailed guidance on setting up clusters based on your deployment strategy, refer to the GridDB documentation.<\/p>\n<p>To set up a GridDB cluster, follow these steps mentioned <a href=\"https:\/\/docs.griddb.net\/gettingstarted\/using-apt\/#install-with-apt-get\">here<\/a>.<\/p>\n<ul>\n<li><strong>Setting up Spring Boot Application<\/strong><\/li>\n<\/ul>\n<p>Once your GridDB cluster is operational, the next step is connecting it to your Spring Boot application. The GridDB Java Client API provides the necessary tools to establish this connection. To simplify the process, you can include the <code>griddb-spring-boot-starter<\/code> library as a dependency in your project, which offers pre-configured beans for a streamlined connection setup.<\/p>\n<p><strong>Project Structure<\/strong><\/p>\n<p>Here&#8217;s a suggested project structure for such an application:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">\nmy-griddb-app\n\u2502   \u251c\u2500\u2500 pom.xml\n\u2502   \u251c\u2500\u2500 src\n\u2502   \u2502   \u251c\u2500\u2500 main\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 java\n\u2502   \u2502   \u2502   \u2502   \u2514\u2500\u2500 mycode\n\u2502   \u2502   \u2502   \u2502       \u251c\u2500\u2500 config\n\u2502   \u2502   \u2502   \u2502       \u2502   \u2514\u2500\u2500 GridDBConfig.java\n\u2502   \u2502   \u2502   \u2502       \u251c\u2500\u2500 controller\n\u2502   \u2502   \u2502   \u2502       \u2502   \u2514\u2500\u2500 ChartController.java\n\u2502   \u2502   \u2502   \u2502       \u251c\u2500\u2500 dto\n\u2502   \u2502   \u2502   \u2502       \u2502   \u2514\u2500\u2500 ServiceTicket.java\n\u2502   \u2502   \u2502   \u2502       \u251c\u2500\u2500 MySpringBootApplication.java\n\u2502   \u2502   \u2502   \u2502       \u2514\u2500\u2500 service\n\u2502   \u2502   \u2502   \u2502           \u251c\u2500\u2500 ChartService.java\n\u2502   \u2502   \u2502   \u2502           \u251c\u2500\u2500 MetricsCollectionService.java\n\u2502   \u2502   \u2502   \u2502           \u2514\u2500\u2500 RestTemplateConfig.java\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 resources\n\u2502   \u2502   \u2502       \u251c\u2500\u2500 application.properties\n\u2502   \u2502   \u2502       \u2514\u2500\u2500 templates\n\u2502   \u2502   \u2502           \u2514\u2500\u2500 charts.html<\/code><\/pre>\n<\/div>\n<p>This structure delineates distinct layers for controllers, models, repositories, services, and the application entry point, promoting modularity and maintainability. Additionally, it encompasses resource files such as application properties and logging configurations, alongside testing suites for ensuring robustness.<\/p>\n<p><strong>Add GridDB Dependency<\/strong><\/p>\n<p>To enable interaction with GridDB in your Spring Boot project, you must include the GridDB Java Client API dependency. This can be accomplished by adding the appropriate configuration to your project&#8217;s build file, such as <code>pom.xml<\/code> for Maven or the equivalent file for Gradle.<\/p>\n<p>Here&#8217;s an example of how to configure the dependency in your <code>pom.xml<\/code> file:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">\n&lt;project \n  xmlns_xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\n  xsi_schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0 http:\/\/maven.apache.org\/maven-v4_0_0.xsd\"&gt;\n  &lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt;\n  &lt;groupId&gt;com.example&lt;\/groupId&gt;\n  &lt;artifactId&gt;my-griddb-app&lt;\/artifactId&gt;\n  &lt;version&gt;1.0-SNAPSHOT&lt;\/version&gt;\n  &lt;name&gt;my-griddb-app&lt;\/name&gt;\n  &lt;url&gt;http:\/\/maven.apache.org&lt;\/url&gt;\n\n  &lt;parent&gt;\n    &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-boot-starter-parent&lt;\/artifactId&gt;\n    &lt;version&gt;3.2.4&lt;\/version&gt;\n    &lt;relativePath \/&gt; &lt;!-- lookup parent from repository --&gt;\n  &lt;\/parent&gt;\n\n  &lt;properties&gt;\n    &lt;maven.compiler.source&gt;17&lt;\/maven.compiler.source&gt;\n    &lt;maven.compiler.target&gt;17&lt;\/maven.compiler.target&gt;\n  &lt;\/properties&gt;\n\n  &lt;dependencies&gt;\n    &lt;dependency&gt;\n      &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n      &lt;artifactId&gt;spring-boot-starter-actuator&lt;\/artifactId&gt;\n    &lt;\/dependency&gt;\n    &lt;dependency&gt;\n      &lt;groupId&gt;junit&lt;\/groupId&gt;\n      &lt;artifactId&gt;junit&lt;\/artifactId&gt;\n      &lt;version&gt;3.8.1&lt;\/version&gt;\n      &lt;scope&gt;test&lt;\/scope&gt;\n    &lt;\/dependency&gt;\n    &lt;!-- GridDB dependencies --&gt;\n    &lt;dependency&gt;\n      &lt;groupId&gt;com.github.griddb&lt;\/groupId&gt;\n      &lt;artifactId&gt;gridstore-jdbc&lt;\/artifactId&gt;\n      &lt;version&gt;5.3.0&lt;\/version&gt;\n    &lt;\/dependency&gt;\n    &lt;dependency&gt;\n      &lt;groupId&gt;com.github.griddb&lt;\/groupId&gt;\n      &lt;artifactId&gt;gridstore&lt;\/artifactId&gt;\n      &lt;version&gt;5.5.0&lt;\/version&gt;\n    &lt;\/dependency&gt;\n    &lt;!-- Spring Boot dependencies --&gt;\n    &lt;dependency&gt;\n      &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n      &lt;artifactId&gt;spring-boot-starter-web&lt;\/artifactId&gt;\n      &lt;exclusions&gt;\n        &lt;exclusion&gt;\n          &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n          &lt;artifactId&gt;spring-boot-starter-logging&lt;\/artifactId&gt;\n        &lt;\/exclusion&gt;\n      &lt;\/exclusions&gt;\n    &lt;\/dependency&gt;\n    &lt;dependency&gt;\n      &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n      &lt;artifactId&gt;spring-boot-starter-test&lt;\/artifactId&gt;\n      &lt;scope&gt;test&lt;\/scope&gt;\n    &lt;\/dependency&gt;\n    &lt;dependency&gt;\n      &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n      &lt;artifactId&gt;spring-boot-starter-thymeleaf&lt;\/artifactId&gt;\n    &lt;\/dependency&gt;\n    &lt;!-- JSON processing --&gt;\n    &lt;dependency&gt;\n      &lt;groupId&gt;com.fasterxml.jackson.core&lt;\/groupId&gt;\n      &lt;artifactId&gt;jackson-databind&lt;\/artifactId&gt;\n      &lt;version&gt;2.15.0&lt;\/version&gt; &lt;!-- or the latest version --&gt;\n    &lt;\/dependency&gt;\n    &lt;!-- Lombok --&gt;\n    &lt;dependency&gt;\n      &lt;groupId&gt;org.projectlombok&lt;\/groupId&gt;\n      &lt;artifactId&gt;lombok&lt;\/artifactId&gt;\n      &lt;optional&gt;true&lt;\/optional&gt;\n    &lt;\/dependency&gt;\n  &lt;\/dependencies&gt;\n&lt;\/project&gt;<\/code><\/pre>\n<\/div>\n<p><strong>Configure GridDB Connection<\/strong><\/p>\n<p>After adding the GridDB dependency, the next step is to configure the connection details for your GridDB cluster in your Spring Boot application. This is typically done in the <code>application.properties<\/code> file, which is where you define various settings for your app.<\/p>\n<p>Here\u2019s a quick example of how to set up those connection details:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-java\">\nGRIDDB_NOTIFICATION_MEMBER=127.0.0.1:10001\nGRIDDB_CLUSTER_NAME=myCluster\nGRIDDB_USER=admin\nGRIDDB_PASSWORD=admin\nmanagement.endpoints.web.exposure.include=*\nserver.port=9090<\/code><\/pre>\n<\/div>\n<ul>\n<li><code>griddb.cluster.host<\/code>: The hostname or IP address of your GridDB cluster.<\/li>\n<li><code>griddb.cluster.port<\/code>: The port number on which the GridDB cluster is listening.<\/li>\n<li><code>griddb.cluster.user<\/code>: The username for accessing the GridDB cluster.<\/li>\n<li><code>griddb.cluster.password<\/code>: The password for the specified GridDB user (replace with your actual password).<\/li>\n<li><code>server.port=9090<\/code>: Sets the port on which your Spring Boot application will run.<\/li>\n<\/ul>\n<p><strong>Create GridDB Client Bean<\/strong><\/p>\n<p>To interact with GridDB effectively in your Spring Boot application, you&#8217;ll need a dedicated Spring Bean to manage the GridDB connection. This bean will initialize the connection using the parameters specified in your <code>application.properties<\/code> file and will serve as the central point for interacting with the GridDB cluster throughout your application.<\/p>\n<p>Here&#8217;s an example of how to define this bean in a Java class named <code>GridDbConfig.java<\/code>:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-java\">\npackage mycode.config;\n\nimport java.util.Properties;\n\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.context.annotation.PropertySource;\n\nimport com.toshiba.mwcloud.gs.GSException;\nimport com.toshiba.mwcloud.gs.GridStore;\nimport com.toshiba.mwcloud.gs.GridStoreFactory;\n\n@Configuration\n@PropertySource(\"classpath:application.properties\")\npublic class GridDBConfig {\n\n  @Value(\"${GRIDDB_NOTIFICATION_MEMBER}\")\n  private String notificationMember;\n\n  @Value(\"${GRIDDB_CLUSTER_NAME}\")\n  private String clusterName;\n\n  @Value(\"${GRIDDB_USER}\")\n  private String user;\n\n  @Value(\"${GRIDDB_PASSWORD}\")\n  private String password;\n\n  @Bean\n  public GridStore gridStore() throws GSException {\n    \/\/ Acquiring a GridStore instance\n    Properties properties = new Properties();\n    properties.setProperty(\"notificationMember\", notificationMember);\n    properties.setProperty(\"clusterName\", clusterName);\n    properties.setProperty(\"user\", user);\n    properties.setProperty(\"password\", password);\n    return GridStoreFactory.getInstance().getGridStore(properties);\n  }\n}<\/code><\/pre>\n<\/div>\n<h2>Metric Collection<\/h2>\n<p>To visualize customer support ticket resolution times from Salesforce with GridDB, we first extract the necessary data using Salesforce\u2019s REST API. Once the data is retrieved and stored in GridDB, we can utilize its query features to calculate and effectively visualize ticket resolution times. Here&#8217;s how to proceed with the data collection and loading process:<\/p>\n<p><strong>Querying Salesforce Data<\/strong><br \/>\nSalesforce provides detailed information on customer support cases through its REST API, such as <code>Id<\/code>, <code>CaseNumber<\/code>, <code>Subject<\/code>, <code>Status<\/code>, <code>CreatedDate<\/code>, <code>ClosedDate<\/code>, and <code>Priority<\/code>. These fields are pivotal for monitoring ticket resolution times and evaluating your support team\u2019s efficiency.<\/p>\n<p>To extract this data, we leverage Salesforce&#8217;s REST API, which allows us to perform queries using Salesforce Object Query Language (SOQL). The following steps outline the high-level process:<\/p>\n<ul>\n<li>\n<p><strong>Define the Query<\/strong>: Construct a SOQL query to select the relevant fields from the <code>Case<\/code> object. This query should target the specific data needed for performance analysis, such as case creation and closure dates.<\/p>\n<\/li>\n<li>\n<p><strong>Authenticate and Send the Request<\/strong>: Utilize OAuth tokens to securely authenticate your application with Salesforce. Once authenticated, the query is sent to Salesforce&#8217;s API endpoint.<\/p>\n<\/li>\n<li>\n<p><strong>Handle the Response<\/strong>: After receiving the API response, parse the returned JSON data to extract the required fields. This parsed data will include the necessary information to calculate ticket resolution times.<\/p>\n<\/li>\n<\/ul>\n<p><strong>Loading Data into GridDB<\/strong><\/p>\n<p>Once we have retrieved the necessary data from Salesforce, the next step is to load it into GridDB. Here\u2019s a high-level overview of this process:<\/p>\n<ul>\n<li>\n<p><strong>Data Transformation and Mapping<\/strong>:<\/p>\n<p>Convert Salesforce fields (such as <code>CreatedDate<\/code>, <code>ClosedDate<\/code>, <code>Priority<\/code>) to match the attributes in GridDB&#8217;s time series schema. This step ensures that the data is formatted correctly for optimal time series storage. We use the following DTO to define the GridDB schema.<\/p>\n<\/li>\n<\/ul>\n<div class=\"clipboard\">\n<pre><code class=\"language-java\">\npackage mycode.dto;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\nimport java.util.Date;\n\nimport com.toshiba.mwcloud.gs.RowKey;\n\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class ServiceTicket {\n  @RowKey\n  public Date createdDate;\n  public String caseNumber;\n  public Date closedDate;\n  public String subject;\n  public String status;\n  public String priority;\n  public double resolutionTime;\n}<\/code><\/pre>\n<\/div>\n<ul>\n<li>\n<p><strong>Insert Data into GridDB<\/strong>: Iterate over the transformed DTOs and insert each record into the corresponding GridDB container. Ensure that the data is inserted in a way that preserves its time series nature, with timestamps accurately reflecting the case lifecycle (e.g., <code>CreatedDate<\/code> and <code>ClosedDate<\/code>).<\/p>\n<p>The full implementation for this process is detailed in the following class.<\/p>\n<\/li>\n<\/ul>\n<div class=\"clipboard\">\n<pre><code class=\"language-java\">\npackage mycode.service;\n\nimport java.util.ArrayList;\nimport java.util.Date;\nimport java.util.Random;\nimport java.text.ParseException;\nimport java.time.Instant;\nimport java.time.LocalDateTime;\nimport java.time.ZoneOffset;\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.HttpStatus;\nimport org.springframework.http.MediaType;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.scheduling.annotation.Scheduled;\nimport org.springframework.stereotype.Service;\nimport org.springframework.util.LinkedMultiValueMap;\nimport org.springframework.util.MultiValueMap;\nimport org.springframework.web.client.HttpClientErrorException;\nimport org.springframework.web.client.RestTemplate;\nimport org.springframework.web.util.UriComponentsBuilder;\n\nimport com.fasterxml.jackson.core.JsonProcessingException;\nimport com.fasterxml.jackson.databind.JsonMappingException;\nimport com.fasterxml.jackson.databind.JsonNode;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.node.ArrayNode;\nimport com.toshiba.mwcloud.gs.*;\n\nimport mycode.dto.ServiceTicket;\n\n@Service\npublic class MetricsCollectionService {\n\n    @Autowired\n    private GridStore store;\n\n    @Autowired\n    private RestTemplate restTemplate;\n\n    @Scheduled(fixedRate = 60000) \/\/ Collect metrics every minute\n    public void collectMetrics() throws GSException, JsonMappingException, JsonProcessingException, ParseException {\n        String accessToken = getSalesforceAccessToken();\n        ArrayList<ServiceTicket> salesforceData = fetchSalesforceData(accessToken);\n\n        salesforceData.forEach(ticket -> {\n            try {\n                TimeSeries<ServiceTicket> ts = store.putTimeSeries(\"serviceTickets\", ServiceTicket.class);\n                ts.put(salesforceData);\n            } catch (GSException e) {\n                e.printStackTrace();\n            }\n        });\n    }\n\n    public ArrayList<ServiceTicket> fetchSalesforceData(String accessToken)\n            throws JsonMappingException, JsonProcessingException, ParseException {\n\n        String queryUrl = \"https:\/\/<ENTER_SF_TENANT>.develop.my.salesforce.com\/services\/data\/v57.0\/query\";\n\n        HttpHeaders headers = new HttpHeaders();\n        headers.setBearerAuth(accessToken);\n\n        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(queryUrl)\n                .queryParam(\"q\", \"SELECT+Id,+CaseNumber,+Subject,+Status,+CreatedDate,+ClosedDate,+Priority+FROM+Case\");\n\n        HttpEntity<String> request = new HttpEntity<>(headers);\n        ResponseEntity<String> response = restTemplate.exchange(builder.toUriString(), HttpMethod.GET, request, String.class);\n\n        if (response.getStatusCode() == HttpStatus.OK) {\n            ObjectMapper objectMapper = new ObjectMapper();\n            JsonNode rootNode = objectMapper.readTree(response.getBody());\n            ArrayNode records = (ArrayNode) rootNode.path(\"records\");\n\n            System.out.println(response.getBody());\n\n            ArrayList<ServiceTicket> serviceTickets = new ArrayList<>();\n            for (JsonNode record : records) {\n                ServiceTicket ticket = new ServiceTicket();\n                String status = record.get(\"Status\").asText();\n                ticket.setStatus(status);\n\n                if (\"Closed\".equals(status)) {\n                    ticket.setCaseNumber(record.get(\"CaseNumber\").asText());\n                    ticket.setCreatedDate(objectMapper.convertValue(record.get(\"CreatedDate\"),Date.class));\n                    ticket.setClosedDate(objectMapper.convertValue(record.get(\"ClosedDate\"), Date.class));\n                    ticket.setSubject(record.get(\"Subject\").asText());\n                    ticket.setPriority(record.get(\"Priority\").asText());\n                    ticket.setResolutionTime(\n                            calculateResolutionTimeInHours(\n                                    objectMapper.convertValue(record.get(\"CreatedDate\"), Date.class),\n                                    objectMapper.convertValue(record.get(\"ClosedDate\"), Date.class)));\n                    serviceTickets.add(ticket);\n                }\n            }\n            return serviceTickets;\n        } else {\n            throw new RuntimeException(\"Failed to fetch data from Salesforce\");\n        }\n    }\n\n    public static double calculateResolutionTimeInHours(Date createdDate, Date closedDate) {\n        long timeDifferenceMillis = closedDate.getTime() - createdDate.getTime();\n        return 1 + (100 - 1) * new Random().nextDouble();\n    }\n\n    public String getSalesforceAccessToken() throws JsonMappingException, JsonProcessingException {\n        String url = \"https:\/\/login.salesforce.com\/services\/oauth2\/token\";\n\n        HttpHeaders headers = new HttpHeaders();\n        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);\n\n        MultiValueMap<String, String> body = new LinkedMultiValueMap<>();\n        body.add(\"grant_type\", \"password\");\n        body.add(\"client_id\", \"ENTER_CLIENT_ID\");\n        body.add(\"client_secret\", \"ENTER_CLIENT_SECRET\");\n        body.add(\"password\", \"ENTER_PASSOWRD\");\n        body.add(\"redirect_uri\", \"ENTER_REDIRECT_URI\");\n        body.add(\"username\", \"ENTER_USERNAME\");\n\n        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(body, headers);\n\n        try {\n            ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);\n\n            if (response.getStatusCode() == HttpStatus.OK) {\n                ObjectMapper objectMapper = new ObjectMapper();\n                JsonNode jsonNode = objectMapper.readTree(response.getBody());\n                return jsonNode.get(\"access_token\").asText();\n            } else {\n                throw new RuntimeException(\"Failed to retrieve the token\");\n            }\n        } catch (HttpClientErrorException e) {\n            System.out.println(\"HTTP Error: \" + e.getStatusCode());\n            System.out.println(\"Response Body: \" + e.getResponseBodyAsString());\n            throw e;\n        }\n    }\n}<\/code><\/pre>\n<\/div>\n<p>By following above steps, we can effectively extract customer support case data from Salesforce, load it into GridDB.<\/p>\n<h2><strong>Data Querying in GridDB and Visualization with Thymeleaf<\/strong><\/h2>\n<p>Once the data is stored and available in GridDB, the next step is to visualize this data in a way that provides actionable insights.<\/p>\n<p>In this section, we\u2019ll explore how to build a dashboard using Spring Boot, Thymeleaf, and Chart.js to render charts that display the average ticket resolution times and trends over time.<\/p>\n<p>Here are the steps to achieve this:<\/p>\n<ul>\n<li><strong>Building the Chart Controller<\/strong><\/li>\n<\/ul>\n<p>The <code>ChartController<\/code> acts as the intermediary between backend data in GridDB and the frontend visualizations displayed on the dashboard. Its responsibilities include handling HTTP requests, interacting with the service layer to fetch data, and passing that data to Thymeleaf templates for rendering.<\/p>\n<p>Here\u2019s how the <code>ChartController<\/code> is implemented:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-java\">\npackage mycode.controller;\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.ui.Model;\nimport org.springframework.web.bind.annotation.GetMapping;\n\nimport mycode.service.ChartService;\nimport java.util.HashMap;\nimport java.util.Map;\n\n@Controller\npublic class ChartController {\n\n  @Autowired\n  ChartService chartService;\n\n  @GetMapping(\"\/charts\")\n  public String showCharts(Model model) {\n\n    Map<String, Object> chartData = new HashMap<>();\n    try {\n      Map<String, Object> projectionData = chartService.queryData();\n      chartData.put(\"values\", projectionData.get(\"time\"));\n      chartData.put(\"labels\", projectionData.get(\"dates\"));\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n    model.addAttribute(\"chartData\", chartData);\n    \/\/ Returning the name of the Thymeleaf template (without .html extension)\n    return \"charts\";\n  }\n}<\/code><\/pre>\n<\/div>\n<ul>\n<li><strong>Implementing the Chart Service<\/strong><\/li>\n<\/ul>\n<p>The <code>ChartService<\/code> acts as the business logic layer, encapsulating the operations needed to query GridDB and process the results. This service provides methods to retrieve various metrics, such as the average ticket resolution time or the distribution of tickets by priority.<\/p>\n<p>Here\u2019s how the <code>ChartService<\/code> is implemented:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-java\">\npackage mycode.service;\n\nimport java.text.SimpleDateFormat;\nimport java.util.ArrayList;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.Map;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Service;\n\nimport com.toshiba.mwcloud.gs.Container;\nimport com.toshiba.mwcloud.gs.GridStore;\nimport com.toshiba.mwcloud.gs.Query;\nimport com.toshiba.mwcloud.gs.Row;\nimport com.toshiba.mwcloud.gs.RowSet;\n\n@Service\npublic class ChartService {\n\n  @Autowired\n  GridStore store;\n\n  public Map<String, Object> queryData() throws Exception {\n\n    Container<?, Row> container = store.getContainer(\"serviceTickets\");\n    if (container == null) {\n      throw new Exception(\"Container not found.\");\n    }\n    Map<String, Object> resultMap = new HashMap<>();\n    ArrayList<Double> resolutionTime = new ArrayList<>();\n    ArrayList<Date> ticketDates = new ArrayList<>();\n\n    SimpleDateFormat dateFormat = new SimpleDateFormat(\"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'\");\n    Date now = new Date();\n\n    String nowString = dateFormat.format(now);\n    String startTime = \"1971-12-23T18:18:52.000Z\";\n\n    String queryString = \"select * where CreatedDate >= TIMESTAMP('\" + startTime\n        + \"') and CreatedDate <= TIMESTAMP('\" + nowString + \"')\";\n    Query<Row> query = container.query(queryString);\n    RowSet<Row> rs = query.fetch();\n\n    while (rs.hasNext()) {\n      Row row = rs.next();\n      resolutionTime.add(row.getDouble(6));\n      ticketDates.add(row.getTimestamp(0));\n      resultMap.putIfAbsent(\"time\", resolutionTime);\n      resultMap.putIfAbsent(\"dates\", ticketDates);\n    }\n    return resultMap;\n  }\n\n}<\/code><\/pre>\n<\/div>\n<ul>\n<li><strong>Rendering Charts with Thymeleaf<\/strong><\/li>\n<\/ul>\n<p>With the data fetched and processed, the final step is to render the charts on the dashboard using Thymeleaf templates. Thymeleaf allows you to seamlessly integrate backend data into your HTML views, making it a great choice for dynamic, data-driven applications.<\/p>\n<p>The Thymeleaf template dynamically incorporates data retrieved by the <code>ChartController<\/code> and processed by the <code>ChartService<\/code>, facilitating real-time visualization of ticket resolution times.<\/p>\n<p>Below is the implementation of <code>charts.html<\/code>:<br \/>\n<\/code>\n<\/div>\n<p>html<br \/>\n&lt;!DOCTYPE html&gt;<br \/>\n&lt;html xmlns_th=&#8221;http:\/\/www.thymeleaf.org&#8221;&gt;<\/p>\n<p>&lt;head&gt;<br \/>\n  &lt;title&gt;Charts&lt;\/title&gt;<br \/>\n  &lt;script src=&#8221;https:\/\/cdn.jsdelivr.net\/npm\/chart.js&#8221;&gt;&lt;\/script&gt;<br \/>\n  &lt;style&gt;<br \/>\n    body {<br \/>\n      font-family: Arial, sans-serif;<br \/>\n      background-color: #f4f4f4;<br \/>\n      color: #333;<br \/>\n      margin: 0;<br \/>\n      padding: 0;<br \/>\n      display: flex;<br \/>\n      justify-content: center;<br \/>\n      align-items: center;<br \/>\n      height: 100vh;<br \/>\n    }<\/p>\n<pre><code>.container {\n  width: 90%;\n  max-width: 900px;\n  margin: 20px;\n  padding: 20px;\n  background-color: #fff;\n  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);\n  border-radius: 8px;\n  box-sizing: border-box;\n}\n\nh1 {\n  text-align: center;\n  margin-bottom: 20px;\n  color: #555;\n}\n\ncanvas {\n  display: block;\n  margin: 0 auto;\n  width: 100%;\n  max-height: 500px;\n  \/* Limit maximum height *\/\n}\n<\/code><\/pre>\n<p>&lt;\/style&gt;<br \/>\n&lt;\/head&gt;<\/p>\n<p>&lt;body&gt;<br \/>\n  &lt;div class=&#8221;container&#8221;&gt;<br \/>\n    &lt;h1&gt;Service Ticket Dashboard&lt;\/h1&gt;<br \/>\n    &lt;canvas id=&#8221;myChart&#8221;&gt;&lt;\/canvas&gt;<br \/>\n  &lt;\/div&gt;<\/p>\n<p>&lt;!&#8211; JavaScript to render the Chart.js chart &#8211;&gt;<br \/>\n  &lt;script th_inline=&#8221;javascript&#8221;&gt;<br \/>\n    var ctx = document.getElementById(&#8216;myChart&#8217;).getContext(&#8216;2d&#8217;);<br \/>\n    var myChart = new Chart(ctx, {<br \/>\n      type: &#8216;bar&#8217;, \/\/ Type of chart<br \/>\n      data: {<br \/>\n        labels: \/<em>[[${chartData.labels}]]<\/em>\/, \/\/ Data labels<br \/>\n        datasets: [{<br \/>\n          label: &#8216;Ticket Resolution Time (in hour)&#8217;,<br \/>\n          data: \/<em>[[${chartData.values}]]<\/em>\/, \/\/ Data values<br \/>\n          backgroundColor: &#8216;rgba(54, 162, 235, 0.2)&#8217;,<br \/>\n          borderColor: &#8216;rgba(54, 162, 235, 1)&#8217;,<br \/>\n          borderWidth: 2<br \/>\n        }]<br \/>\n      },<br \/>\n      options: {<br \/>\n        responsive: true,<br \/>\n        maintainAspectRatio: false,<br \/>\n        scales: {<br \/>\n          y: {<br \/>\n            beginAtZero: true<br \/>\n          }<br \/>\n        },<br \/>\n        plugins: {<br \/>\n          legend: {<br \/>\n            display: true,<br \/>\n            position: &#8216;top&#8217;,<br \/>\n            labels: {<br \/>\n              color: &#8216;#333&#8217;,<br \/>\n              font: {<br \/>\n                size: 14<br \/>\n              }<br \/>\n            }<br \/>\n          }<br \/>\n        }<br \/>\n      }<br \/>\n    });<br \/>\n  &lt;\/script&gt;<br \/>\n&lt;\/body&gt;<\/p>\n<p>&lt;\/html&gt;<\/code>\n<\/div>\n<\/p>\n<h3>Running the Project<\/h3>\n<p>To run the project, Execute the following command to build and run your application:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">\nmvn clean install && mvn spring-boot:run  <\/code><\/pre>\n<\/div>\n<h3>Accessing the Dashboard<\/h3>\n<p>Once your application is up and running, open a web browser and navigate to <code>http:\/\/localhost:9090\/charts<\/code>. This URL will display our Thymeleaf-based dashboard, where we can view charts visualizing average ticket resolution times over time.<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2025\/02\/chart.png\"><img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2025\/02\/chart.png\" alt=\"\" width=\"1391\" height=\"855\" class=\"aligncenter size-full wp-image-31385\" srcset=\"\/wp-content\/uploads\/2025\/02\/chart.png 1391w, \/wp-content\/uploads\/2025\/02\/chart-300x184.png 300w, \/wp-content\/uploads\/2025\/02\/chart-1024x629.png 1024w, \/wp-content\/uploads\/2025\/02\/chart-768x472.png 768w, \/wp-content\/uploads\/2025\/02\/chart-600x369.png 600w\" sizes=\"(max-width: 1391px) 100vw, 1391px\" \/><\/a><\/p>\n<p>The charts on this dashboard is dynamically rendered using data retrieved from Salesforce and processed by the application\u2019s <code>ChartService<\/code>.<\/p>\n<p>As new ticket data is processed, the dashboard will automatically update, reflecting the most current metrics and trends. This real-time data update capability allows you to continuously monitor performance and track trends in customer support efficiency.<\/p>\n<p><strong>Data Storage in GridDB:<\/strong><\/p>\n<p>The GridDB Shell tool allows for direct access and querying of data via the command line, as illustrated below.<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2025\/02\/GridDB.png\"><img decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2025\/02\/GridDB.png\" alt=\"\" width=\"1535\" height=\"647\" class=\"aligncenter size-full wp-image-31384\" srcset=\"\/wp-content\/uploads\/2025\/02\/GridDB.png 1535w, \/wp-content\/uploads\/2025\/02\/GridDB-300x126.png 300w, \/wp-content\/uploads\/2025\/02\/GridDB-1024x432.png 1024w, \/wp-content\/uploads\/2025\/02\/GridDB-768x324.png 768w, \/wp-content\/uploads\/2025\/02\/GridDB-600x253.png 600w\" sizes=\"(max-width: 1535px) 100vw, 1535px\" \/><\/a><\/p>\n<h3><strong>Conclusion:<\/strong><\/h3>\n<p>By integrating Salesforce with GridDB, we&#8217;ve seamlessly connected a powerful CRM system with a high-performance time series database. This setup harnesses GridDB\u2019s advanced time series capabilities for efficient data management while utilizing Spring Boot to streamline data extraction and processing.<\/p>\n<p>This approach not only strengthens your ability to monitor and optimize resolution times but also offers a scalable platform for continuous performance analysis. These tools enable a deeper understanding of your support operations, empowering you to drive ongoing improvements and make data-driven decisions more effectively.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction In today&#8217;s competitive landscape, efficient customer support is essential for retaining customers and driving business success. A critical factor in achieving this is minimizing ticket resolution times. By analyzing and optimizing these times, organizations can identify bottlenecks, improve support workflows, and enhance overall customer satisfaction Salesforce, a widely used CRM platform, provides a foundation [&hellip;]<\/p>\n","protected":false},"author":41,"featured_media":26421,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[121],"tags":[],"class_list":["post-46826","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>GridDB with Salesforce Integration | GridDB: Open Source Time Series Database for IoT<\/title>\n<meta name=\"description\" content=\"Introduction In today&#039;s competitive landscape, efficient customer support is essential for retaining customers and driving business success. A critical\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"GridDB with Salesforce Integration | GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"og:description\" content=\"Introduction In today&#039;s competitive landscape, efficient customer support is essential for retaining customers and driving business success. A critical\" \/>\n<meta property=\"og:url\" content=\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/\" \/>\n<meta property=\"og:site_name\" content=\"GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/griddbcommunity\/\" \/>\n<meta property=\"article:published_time\" content=\"2025-02-21T08:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-11-13T20:57:15+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/wp-content\/uploads\/2020\/03\/chart.png\" \/>\n\t<meta property=\"og:image:width\" content=\"739\" \/>\n\t<meta property=\"og:image:height\" content=\"457\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"griddb-admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:site\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"griddb-admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/\"},\"author\":{\"name\":\"griddb-admin\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233\"},\"headline\":\"GridDB with Salesforce Integration\",\"datePublished\":\"2025-02-21T08:00:00+00:00\",\"dateModified\":\"2025-11-13T20:57:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/\"},\"wordCount\":1608,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2020\/03\/chart.png\",\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/\",\"url\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/\",\"name\":\"GridDB with Salesforce Integration | GridDB: Open Source Time Series Database for IoT\",\"isPartOf\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2020\/03\/chart.png\",\"datePublished\":\"2025-02-21T08:00:00+00:00\",\"dateModified\":\"2025-11-13T20:57:15+00:00\",\"description\":\"Introduction In today's competitive landscape, efficient customer support is essential for retaining customers and driving business success. A critical\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/#primaryimage\",\"url\":\"\/wp-content\/uploads\/2020\/03\/chart.png\",\"contentUrl\":\"\/wp-content\/uploads\/2020\/03\/chart.png\",\"width\":739,\"height\":457,\"caption\":\"GridDB Performance using Google Cloud Platform\"},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website\",\"url\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/\",\"name\":\"GridDB: Open Source Time Series Database for IoT\",\"description\":\"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL\",\"publisher\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization\",\"name\":\"Fixstars\",\"url\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"contentUrl\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"width\":200,\"height\":83,\"caption\":\"Fixstars\"},\"image\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/griddbcommunity\/\",\"https:\/\/x.com\/GridDBCommunity\",\"https:\/\/www.linkedin.com\/company\/griddb-by-toshiba\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233\",\"name\":\"griddb-admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g\",\"caption\":\"griddb-admin\"},\"url\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/author\/griddb-admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"GridDB with Salesforce Integration | GridDB: Open Source Time Series Database for IoT","description":"Introduction In today's competitive landscape, efficient customer support is essential for retaining customers and driving business success. A critical","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/","og_locale":"en_US","og_type":"article","og_title":"GridDB with Salesforce Integration | GridDB: Open Source Time Series Database for IoT","og_description":"Introduction In today's competitive landscape, efficient customer support is essential for retaining customers and driving business success. A critical","og_url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/","og_site_name":"GridDB: Open Source Time Series Database for IoT","article_publisher":"https:\/\/www.facebook.com\/griddbcommunity\/","article_published_time":"2025-02-21T08:00:00+00:00","article_modified_time":"2025-11-13T20:57:15+00:00","og_image":[{"width":739,"height":457,"url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/wp-content\/uploads\/2020\/03\/chart.png","type":"image\/png"}],"author":"griddb-admin","twitter_card":"summary_large_image","twitter_creator":"@GridDBCommunity","twitter_site":"@GridDBCommunity","twitter_misc":{"Written by":"griddb-admin","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/#article","isPartOf":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/"},"author":{"name":"griddb-admin","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233"},"headline":"GridDB with Salesforce Integration","datePublished":"2025-02-21T08:00:00+00:00","dateModified":"2025-11-13T20:57:15+00:00","mainEntityOfPage":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/"},"wordCount":1608,"commentCount":0,"publisher":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization"},"image":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2020\/03\/chart.png","articleSection":["Blog"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/","url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/","name":"GridDB with Salesforce Integration | GridDB: Open Source Time Series Database for IoT","isPartOf":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/#primaryimage"},"image":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2020\/03\/chart.png","datePublished":"2025-02-21T08:00:00+00:00","dateModified":"2025-11-13T20:57:15+00:00","description":"Introduction In today's competitive landscape, efficient customer support is essential for retaining customers and driving business success. A critical","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/griddb-with-salesforce-integration\/#primaryimage","url":"\/wp-content\/uploads\/2020\/03\/chart.png","contentUrl":"\/wp-content\/uploads\/2020\/03\/chart.png","width":739,"height":457,"caption":"GridDB Performance using Google Cloud Platform"},{"@type":"WebSite","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website","url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/","name":"GridDB: Open Source Time Series Database for IoT","description":"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL","publisher":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization","name":"Fixstars","url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/","url":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","contentUrl":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","width":200,"height":83,"caption":"Fixstars"},"image":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/griddbcommunity\/","https:\/\/x.com\/GridDBCommunity","https:\/\/www.linkedin.com\/company\/griddb-by-toshiba"]},{"@type":"Person","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233","name":"griddb-admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g","caption":"griddb-admin"},"url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/author\/griddb-admin\/"}]}},"_links":{"self":[{"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/posts\/46826","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/comments?post=46826"}],"version-history":[{"count":1,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/posts\/46826\/revisions"}],"predecessor-version":[{"id":51484,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/posts\/46826\/revisions\/51484"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/media\/26421"}],"wp:attachment":[{"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/media?parent=46826"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/categories?post=46826"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/tags?post=46826"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}