Skip to content

Commit

Permalink
Merge pull request #787 from ombhardwajj/metabaseSetupFix
Browse files Browse the repository at this point in the history
Corrected the metabase setup code
  • Loading branch information
himeshr authored Oct 25, 2024
2 parents ebb7e03 + 5ab3b2e commit 15a4577
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import org.avni.server.domain.metabase.*;
import org.avni.server.util.ObjectMapperSingleton;
import org.avni.server.util.S;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.stereotype.Repository;
Expand All @@ -17,7 +18,7 @@ public class DatabaseRepository extends MetabaseConnector {
private final ObjectMapper objectMapper;
public DatabaseRepository(RestTemplateBuilder restTemplateBuilder) {
super(restTemplateBuilder);
this.objectMapper = new ObjectMapper();
this.objectMapper = ObjectMapperSingleton.getObjectMapper();
}

public Database save(Database database) {
Expand All @@ -33,7 +34,6 @@ public Database getDatabaseByName(Database database) {
String jsonResponse = getForObject(url, String.class);

try {
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(jsonResponse);
JsonNode dataArray = rootNode.path("data");

Expand All @@ -43,7 +43,7 @@ public Database getDatabaseByName(Database database) {
return db;
}
}
throw new RuntimeException("Database with name " + database.getName() + " not found.");
return null;
} catch (Exception e) {
throw new RuntimeException("Failed to retrieve database", e);
}
Expand Down Expand Up @@ -74,16 +74,14 @@ public CollectionInfoResponse getCollectionByName(Database database) {
String url = metabaseApiUrl + "/collection";
try {
String jsonResponse = getForObject(url, String.class);

ObjectMapper objectMapper = new ObjectMapper();
List<CollectionInfoResponse> collections = objectMapper.readValue(
jsonResponse, new TypeReference<List<CollectionInfoResponse>>() {}
);

return collections.stream()
.filter(collection -> collection.getName().equals(database.getName()))
.findFirst()
.orElseThrow(() -> new RuntimeException("Collection with name " + database.getName() + " not found."));
.orElseThrow(null);
} catch (Exception e) {
throw new RuntimeException("Failed to retrieve collection", e);
}
Expand All @@ -94,7 +92,7 @@ public void createQuestionForTable(Database database, TableDetails tableDetails,
FieldDetails joinField2 = getFieldDetailsByName(database, tableDetails, destinationField);

ArrayNode joinsArray = objectMapper.createArrayNode();
MetabaseQuery query = new MetabaseQueryBuilder(database, joinsArray, objectMapper)
MetabaseQuery query = new MetabaseQueryBuilder(database, joinsArray)
.forTable(tableDetails)
.joinWith(addressTableDetails, joinField1, joinField2)
.build();
Expand All @@ -108,11 +106,11 @@ public void createQuestionForTable(Database database, TableDetails tableDetails,
getCollectionByName(database).getIdAsInt()
);

postForObject(metabaseApiUrl + "/card", requestBody.toJson(objectMapper), JsonNode.class);
postForObject(metabaseApiUrl + "/card", requestBody.toJson(), JsonNode.class);
}

public void createQuestionForASingleTable(Database database, TableDetails tableDetails) {
MetabaseQuery query = new MetabaseQueryBuilder(database, objectMapper.createArrayNode(), objectMapper)
MetabaseQuery query = new MetabaseQueryBuilder(database, objectMapper.createArrayNode())
.forTable(tableDetails)
.build();

Expand All @@ -125,7 +123,7 @@ public void createQuestionForASingleTable(Database database, TableDetails tableD
getCollectionByName(database).getIdAsInt()
);

postForObject(metabaseApiUrl + "/card", requestBody.toJson(objectMapper), JsonNode.class);
postForObject(metabaseApiUrl + "/card", requestBody.toJson(), JsonNode.class);
}

public FieldDetails getFieldDetailsByName(Database database, TableDetails tableDetails, FieldDetails fieldDetails) {
Expand Down Expand Up @@ -180,7 +178,7 @@ public DatabaseSyncStatus getInitialSyncStatus(Database database) {

public DatasetResponse getDataset(DatasetRequestBody requestBody) {
String url = metabaseApiUrl + "/dataset";
String jsonRequestBody = requestBody.toJson(objectMapper).toString();
String jsonRequestBody = requestBody.toJson().toString();
String jsonResponse = postForObject(url, jsonRequestBody, String.class);
try {
return objectMapper.readValue(jsonResponse, DatasetResponse.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package org.avni.server.dao.metabase;

import org.avni.server.domain.metabase.GroupPermissionsService;
import org.avni.server.domain.metabase.GroupPermissionsGraphResponse;
import org.avni.server.domain.metabase.Group;
import org.avni.server.domain.metabase.GroupPermissionsBody;
import org.avni.server.domain.metabase.*;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.stereotype.Repository;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Repository
Expand All @@ -21,7 +20,6 @@ public Group save(Group permissionsGroup) {
String url = metabaseApiUrl + "/permissions/group";
GroupPermissionsBody body = new GroupPermissionsBody(permissionsGroup.getName());
HttpEntity<Map<String, Object>> entity = createJsonEntity(body);

Group response = restTemplate.postForObject(url, entity, Group.class);
return response;
}
Expand All @@ -31,9 +29,36 @@ public GroupPermissionsGraphResponse getPermissionsGraph() {
return getForObject(url, GroupPermissionsGraphResponse.class);
}

public void updatePermissionsGraph(GroupPermissionsService permissions, int groupId, int databaseId) {
public void updatePermissionsGraph(GroupPermissionsService permissions) {
String url = metabaseApiUrl + "/permissions/graph";
Map<String, Object> requestBody = permissions.getUpdatedPermissionsGraph();
sendPutRequest(url, requestBody);
}

public List<GroupPermissionResponse> getAllGroups() {
String url = metabaseApiUrl + "/permissions/group";
GroupPermissionResponse[] response = getForObject(url, GroupPermissionResponse[].class);
return Arrays.asList(response);
}

public void updateGroupPermissions(int groupId, int databaseId) {
GroupPermissionsService groupPermissions = new GroupPermissionsService(getPermissionsGraph());
groupPermissions.updatePermissions(groupId, databaseId);
updatePermissionsGraph(groupPermissions);
}


public Group findOrCreateGroup(String name, int databaseId, int collectionId) {
List<GroupPermissionResponse> existingGroups = getAllGroups();

for (GroupPermissionResponse group : existingGroups) {
if (group.getName().equals(name)) {
return new Group(group.getName(), group.getId());
}
}

Group newGroup = save(new Group(name));
updateGroupPermissions(newGroup.getId(), databaseId);
return newGroup;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.HashMap;
import java.util.Map;

import org.avni.server.dao.metabase.CollectionPermissionsRepository;
import org.springframework.stereotype.Component;

@Component
Expand Down Expand Up @@ -55,4 +56,9 @@ public Map<String, Object> getUpdatedPermissionsGraph() {
public CollectionPermissionsGraphResponse getPermissionsGraph() {
return permissionsGraph;
}

public void updateAndSavePermissions(CollectionPermissionsRepository collectionPermissionsRepository, int groupId, int collectionId) {
updatePermissions(groupId, collectionId);
collectionPermissionsRepository.updateCollectionPermissions(this, groupId, collectionId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.avni.server.util.ObjectMapperSingleton;

public class DatasetRequestBody {

Expand All @@ -13,16 +14,16 @@ public DatasetRequestBody(Database database, TableDetails table) {
this.table = table;
}

public ObjectNode toJson(ObjectMapper objectMapper) {
ObjectNode rootNode = objectMapper.createObjectNode();
public ObjectNode toJson() {
ObjectNode rootNode = ObjectMapperSingleton.getObjectMapper().createObjectNode();
rootNode.put("database", database.getId());

ObjectNode queryNode = objectMapper.createObjectNode();
ObjectNode queryNode = ObjectMapperSingleton.getObjectMapper().createObjectNode();
queryNode.put("source-table", table.getId());

rootNode.set("query", queryNode);
rootNode.put("type", "query");
rootNode.set("parameters", objectMapper.createArrayNode());
rootNode.set("parameters", ObjectMapperSingleton.getObjectMapper().createArrayNode());

return rootNode;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.avni.server.util.ObjectMapperSingleton;

public enum FieldAttribute {
ALL("all"),
Expand All @@ -24,8 +25,8 @@ public String getAttributeName() {
return attributeName;
}

public ObjectNode toJson(ObjectMapper objectMapper, Object value) {
ObjectNode attributeNode = objectMapper.createObjectNode();
public ObjectNode toJson(Object value) {
ObjectNode attributeNode = ObjectMapperSingleton.getObjectMapper().createObjectNode();
attributeNode.put(attributeName, value.toString());
return attributeNode;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.avni.server.domain.metabase;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class GroupPermissionResponse {
private int id;
private String name;
private int memberCount;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getMemberCount() {
return memberCount;
}

public void setMemberCount(int memberCount) {
this.memberCount = memberCount;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.avni.server.util.ObjectMapperSingleton;

public class MetabaseQueryBuilder {
private final Database database;
private final ArrayNode joinsArray;
private final ObjectMapper objectMapper;
private ObjectNode queryNode;

public MetabaseQueryBuilder(Database database, ArrayNode joinsArray, ObjectMapper objectMapper) {
public MetabaseQueryBuilder(Database database, ArrayNode joinsArray) {
this.database = database;
this.joinsArray = joinsArray;
this.objectMapper = objectMapper;
this.objectMapper = ObjectMapperSingleton.getObjectMapper();
this.queryNode = objectMapper.createObjectNode();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.avni.server.domain.metabase;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.avni.server.util.ObjectMapperSingleton;

// Refer docs : https://www.metabase.com/docs/latest/api/card#post-apicard
public class MetabaseRequestBody {
Expand All @@ -24,11 +24,11 @@ public MetabaseRequestBody(String name, MetabaseQuery datasetQuery, Visualizatio
this.collectionId = collectionId;
}

public ObjectNode toJson(ObjectMapper objectMapper) {
ObjectNode rootNode = objectMapper.createObjectNode();
public ObjectNode toJson() {
ObjectNode rootNode = ObjectMapperSingleton.getObjectMapper().createObjectNode();
rootNode.put("name", name);

ObjectNode datasetQueryNode = objectMapper.createObjectNode();
ObjectNode datasetQueryNode = ObjectMapperSingleton.getObjectMapper().createObjectNode();
datasetQueryNode.put("database", datasetQuery.getDatabaseId());
datasetQueryNode.put("type", "query");
datasetQueryNode.set("query", datasetQuery.toJson());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@
import org.avni.server.domain.metabase.*;
import org.avni.server.service.OrganisationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;


@Service
public class MetabaseService {

Expand Down Expand Up @@ -44,36 +42,47 @@ public void setupMetabase() {
String name = currentOrganisation.getName();
String dbUser = currentOrganisation.getDbUser();

Database database = databaseRepository.save(new Database(name, "postgres", new DatabaseDetails(avniDatabase, dbUser)));
this.globalDatabase = database;

CollectionResponse metabaseCollection = collectionRepository.save(new CreateCollectionRequest(name, name + " collection"));
this.globalCollection = new CollectionInfoResponse(null, metabaseCollection.getId(), false);
globalDatabase = databaseRepository.getDatabaseByName(new Database(name));
if (globalDatabase == null) {
Database newDatabase = new Database(name, "postgres", new DatabaseDetails(avniDatabase, dbUser));
globalDatabase = databaseRepository.save(newDatabase);
}

Group metabaseGroup = groupPermissionsRepository.save(new Group(name));
globalCollection = databaseRepository.getCollectionByName(globalDatabase);
if (globalCollection == null) {
CollectionResponse metabaseCollection = collectionRepository.save(new CreateCollectionRequest(name, name + " collection"));
globalCollection = new CollectionInfoResponse(null, metabaseCollection.getId(), false);
}

GroupPermissionsService groupPermissions = new GroupPermissionsService(groupPermissionsRepository.getPermissionsGraph());
groupPermissions.updatePermissions(metabaseGroup.getId(), database.getId());
groupPermissionsRepository.updatePermissionsGraph(groupPermissions, metabaseGroup.getId(), database.getId());
Group metabaseGroup = groupPermissionsRepository.findOrCreateGroup(name, globalDatabase.getId(), globalCollection.getIdAsInt());

CollectionPermissionsService collectionPermissions = new CollectionPermissionsService(collectionPermissionsRepository.getCollectionPermissionsGraph());
collectionPermissions.updatePermissions(metabaseGroup.getId(), metabaseCollection.getId());
collectionPermissionsRepository.updateCollectionPermissions(collectionPermissions, metabaseGroup.getId(), metabaseCollection.getId());
CollectionPermissionsService collectionPermissions = new CollectionPermissionsService(
collectionPermissionsRepository.getCollectionPermissionsGraph()
);
collectionPermissions.updateAndSavePermissions(collectionPermissionsRepository, metabaseGroup.getId(), globalCollection.getIdAsInt());
}

public Database getGlobalDatabase() {
if (globalDatabase == null) {
Organisation currentOrganisation = organisationService.getCurrentOrganisation();
globalDatabase = databaseRepository.getDatabaseByName(new Database(currentOrganisation.getName()));
if (globalDatabase == null) {
throw new RuntimeException("Global database not found.");
}
}
return globalDatabase;
}


public CollectionInfoResponse getGlobalCollection() {
if (globalCollection == null) {
Organisation currentOrganisation = organisationService.getCurrentOrganisation();
globalCollection = databaseRepository.getCollectionByName(new Database(currentOrganisation.getName()));
if (globalCollection == null) {
throw new RuntimeException("Global database not found.");
}
}
return globalCollection;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,4 @@ public void createQuestions() throws Exception{
public SyncStatus getSyncStatus() {
return databaseService.getInitialSyncStatus();
}

}

0 comments on commit 15a4577

Please sign in to comment.