Skip to content

Commit

Permalink
Merge pull request #98 from tejash-jl/schemaAPI
Browse files Browse the repository at this point in the history
added functionality to support dynamic schemas
  • Loading branch information
dileepbapat authored Mar 7, 2022
2 parents 727f1d8 + c4d4675 commit 1f1dd9d
Show file tree
Hide file tree
Showing 26 changed files with 777 additions and 70 deletions.
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,10 @@ target

# Properties
config-*.properties
application.properties
application.yml

# Json-LD
schema-configuration.jsonld
schema-configuration-school-test.jsonld
frame.json

# Shex file
validations.shex
Expand Down
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ build: java/registry/target/registry.jar

java/registry/target/registry.jar: $(SOURCES)
echo $(SOURCES)
sh configure-dependencies.sh
cd java && ./mvnw clean install

test: build
Expand All @@ -21,5 +22,5 @@ test: build
@docker-compose down

clean:
@rm -rf target
@rm java/registry/target/registry.jar
@rm -rf target || true
@rm java/registry/target/registry.jar || true
10 changes: 5 additions & 5 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ services:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
registry:
image: dockerhub/sunbird-rc-core:v0.0.3
image: dockerhub/sunbird-rc-core:v0.0.4
volumes:
- ${PWD}/java/registry/src/main/resources/public/_schemas:/home/sunbirdrc/config/public/_schemas

Expand Down Expand Up @@ -77,7 +77,7 @@ services:
db:
condition: service_started
claim-ms:
image: dockerhub/sunbird-rc-claim-ms:v0.0.3
image: dockerhub/sunbird-rc-claim-ms:v0.0.4
environment:
- connectionInfo_uri=jdbc:postgresql://db:5432/registry
- connectionInfo_username=postgres
Expand All @@ -91,13 +91,13 @@ services:
registry:
condition: service_started
certificate-signer:
image: dockerhub/sunbird-rc-certificate-signer:v0.0.3
image: dockerhub/sunbird-rc-certificate-signer:v0.0.4
environment:
- PORT=8079
ports:
- "8079:8079"
certificate-api:
image: dockerhub/sunbird-rc-certificate-api:v0.0.3
image: dockerhub/sunbird-rc-certificate-api:v0.0.4
environment:
- PORT=8078
ports:
Expand All @@ -119,6 +119,6 @@ services:
timeout: 20s
retries: 3
notification-ms:
image: dockerhub/sunbird-rc-notification-service:v0.0.3
image: dockerhub/sunbird-rc-notification-service:v0.0.4
ports:
- "8765:8765"
6 changes: 4 additions & 2 deletions java/apitest/src/test/java/tests/registry/certificate.feature
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ Feature: Get certificate pdf
* def certUrl = "http://localhost:8078"
* def templateBody = {"certificate": "{\"name\":\"Test Name\", \"dob\":\"2002-12-22\"}","templateUrl": "http://registry:8081/api/v1/templates/Student.html"}
Scenario:
And header Accept = 'application/pdf'
Given url certUrl
Given path "api/v1/certificatePDF"
Given path "api/v1/certificate"
And request templateBody
When method post
Then status 200
#* print response

Scenario:
And header Accept = 'application/pdf'
Given url certUrl
Given path "api/v1/certificatePDF"
Given path "api/v1/certificate"
And request {"certificate":"","templateUrl": "http://registry:8081/api/v1/templates/Student.html"}
When method post
Then status 400
Expand Down
11 changes: 11 additions & 0 deletions java/claim/src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
server.port=8082

spring.datasource.url=${connectionInfo_uri:jdbc:postgresql://0.0.0.0:5432/registry}
spring.datasource.username=${connectionInfo_username:postgres}
spring.datasource.password=${connectionInfo_password:postgres}

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=update

spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
sunbirdrc.url=${sunbirdrc_url:http://localhost:8081}
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public class Constants {

//class path for json resources from _schemas folder
public static final String RESOURCE_LOCATION = "classpath*:public/_schemas/*.json";
public static final String INTERNAL_RESOURCE_LOCATION = "classpath*:internal/_schemas/*.json";

//elastic search document type
public static final String ES_DOC_TYPE = "_doc";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package dev.sunbirdrc.registry.middleware.util;

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class Did {
private String method;
private String methodIdentifier;

public static Did parse(String didText) throws Exception {
String[] split = didText.split(":");
if (split.length == 3) {
return Did.builder().method(split[1]).methodIdentifier(split[2]).build();
} else {
throw new Exception("Invalid Did Format: " + didText);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.KeycloakBuilder;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.admin.client.resource.UsersResource;
import org.keycloak.admin.client.resource.*;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -66,8 +66,9 @@ private Keycloak buildKeycloak() {
public String createUser(String entityName, String userName, String email, String mobile) throws OwnerCreationException {
logger.info("Creating user with mobile_number : " + userName);
UserRepresentation newUser = createUserRepresentation(entityName, userName, email, mobile);
GroupRepresentation entityGroup = createGroupRepresentation(entityName);
keycloak.realm(realm).groups().add(entityGroup);
UsersResource usersResource = keycloak.realm(realm).users();

Response response = usersResource.create(newUser);
if (response.getStatus() == 201) {
logger.info("Response | Status: {} | Status Info: {}", response.getStatus(), response.getStatusInfo());
Expand All @@ -85,6 +86,12 @@ public String createUser(String entityName, String userName, String email, Strin
}
}

private GroupRepresentation createGroupRepresentation(String entityName) {
GroupRepresentation groupRepresentation = new GroupRepresentation();
groupRepresentation.setName(entityName);
return groupRepresentation;
}

private String updateExistingUserAttributes(String entityName, String userName, String email, String mobile) throws OwnerCreationException {
Optional<UserResource> userRepresentationOptional = getUserByUsername(userName);
if (userRepresentationOptional.isPresent()) {
Expand All @@ -110,6 +117,7 @@ private UserRepresentation createUserRepresentation(String entityName, String us
credentialRepresentation.setType(PASSWORD);
newUser.setCredentials(Collections.singletonList(credentialRepresentation));
}
newUser.setGroups(Collections.singletonList(entityName));
newUser.setEmail(email);
newUser.singleAttribute(MOBILE_NUMBER, mobile);
newUser.singleAttribute(EMAIL, email);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@ public class Constants {
public static final String CLAIM_REJECTED = "CLAIM_REJECTED";
public static final String USER_ANONYMOUS = "anonymous";
public static final String ATTESTATION_POLICY = "AttestationPolicy";
public static final String Schema = "Schema";
public static final String Template = "template";
public static final String TemplateKey = "template-key";
public final static String TITLE = "title";
public final static String PATH = "path";
public final static String URL = "url";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package dev.sunbirdrc.registry.config;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import dev.sunbirdrc.pojos.APIMessage;
import dev.sunbirdrc.registry.service.ISearchService;
import dev.sunbirdrc.registry.util.DefinitionsManager;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import java.io.IOException;

import static dev.sunbirdrc.registry.Constants.Schema;

@Component
public class SchemaLoader implements ApplicationListener<ContextRefreshedEvent> {
public static final Logger logger = LoggerFactory.getLogger(SchemaLoader.class);

@Autowired
private ISearchService searchService;

@Autowired
private DefinitionsManager definitionsManager;

@Override
public void onApplicationEvent(@NotNull ContextRefreshedEvent contextRefreshedEvent) {
loadSchemasFromDB();
}

private void loadSchemasFromDB() {
ObjectNode objectNode = JsonNodeFactory.instance.objectNode();
objectNode.set("entityType", JsonNodeFactory.instance.arrayNode().add(Schema));
objectNode.set("filters", JsonNodeFactory.instance.objectNode());
try {
JsonNode searchResults = searchService.search(objectNode);
searchResults.get(Schema).forEach(schemaNode -> {
definitionsManager.appendNewDefinition(schemaNode.get(Schema.toLowerCase()));
});
logger.info("Loaded {} schema from DB", searchResults.get(Schema).size());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import dev.sunbirdrc.registry.transform.Configuration;
import dev.sunbirdrc.registry.transform.Data;
import dev.sunbirdrc.registry.transform.ITransformer;
import dev.sunbirdrc.registry.util.Definition;
import dev.sunbirdrc.registry.util.RecordIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -174,6 +175,23 @@ public ResponseEntity<Response> getRegisters(@RequestHeader HttpHeaders header)
return new ResponseEntity<>(response, HttpStatus.OK);
}

@RequestMapping(value = "/registry/{entity}", method = RequestMethod.GET)
public ResponseEntity<Response> getRegisters(@PathVariable String entity, @RequestHeader HttpHeaders header) {
ResponseParams responseParams = new ResponseParams();
Response response = new Response(Response.API_ID.READ, "OK", responseParams);
try {
Definition definition = definitionsManager.getDefinition(entity);
response.setResult(definition);
logger.info("get registers,{}", entity);
} catch (Exception e) {
logger.error("Read Api Exception occurred ", e);
responseParams.setErrmsg(e.getMessage());
responseParams.setStatus(Response.Status.UNSUCCESSFUL);
}

return new ResponseEntity<>(response, HttpStatus.OK);
}

@ResponseBody
@RequestMapping(value = "/update", method = RequestMethod.POST)
public ResponseEntity<Response> updateEntity() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@
import dev.sunbirdrc.registry.exception.UnAuthorizedException;
import dev.sunbirdrc.registry.middleware.MiddlewareHaltException;
import dev.sunbirdrc.registry.middleware.util.Constants;
import dev.sunbirdrc.registry.middleware.util.Did;
import dev.sunbirdrc.registry.middleware.util.JSONUtil;
import dev.sunbirdrc.registry.middleware.util.OSSystemFields;
import dev.sunbirdrc.registry.service.FileStorageService;
import dev.sunbirdrc.registry.service.ICertificateService;
import dev.sunbirdrc.registry.transform.Configuration;
import dev.sunbirdrc.registry.transform.Data;
import dev.sunbirdrc.registry.transform.ITransformer;
import dev.sunbirdrc.validators.ValidationException;
import org.apache.commons.lang3.StringUtils;
import org.keycloak.KeycloakPrincipal;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.slf4j.Logger;
Expand All @@ -37,6 +40,8 @@
import java.lang.reflect.InvocationTargetException;
import java.util.*;

import static dev.sunbirdrc.registry.Constants.*;

@RestController
public class RegistryEntityController extends AbstractController {

Expand All @@ -45,6 +50,9 @@ public class RegistryEntityController extends AbstractController {
@Autowired
private ICertificateService certificateService;

@Autowired
private FileStorageService fileStorageService;

@Value("${authentication.enabled:true}") boolean authenticationEnabled;
@Value("${certificate.enableExternalTemplates:false}") boolean externalTemplatesEnabled;

Expand Down Expand Up @@ -216,13 +224,7 @@ public ResponseEntity<Object> postEntity(
newRootNode.set(entityName, rootNode);

try {
String userId;
if (registryHelper.doesEntityContainOwnershipAttributes(entityName)) {
registryHelper.authorizeManageEntity(request, entityName);
userId = registryHelper.getUserId(request, entityName);
} else {
userId= dev.sunbirdrc.registry.Constants.USER_ANONYMOUS;
}
String userId = registryHelper.authorizeManageEntity(request, entityName);
String label = registryHelper.addEntityAndSign(newRootNode, userId);
Map resultMap = new HashMap();
resultMap.put(dbConnectionInfoMgr.getUuidPropertyName(), label);
Expand Down Expand Up @@ -449,20 +451,36 @@ public ResponseEntity<Object> getEntityType(@PathVariable String entityName,
return new ResponseEntity<>(certificateService.getCertificate(node,
entityName,
request.getHeader(HttpHeaders.ACCEPT),
getTemplateUrlFromRequest(request)
getTemplateUrlFromRequest(request, entityName)
), HttpStatus.OK);
} catch (Exception exception) {
exception.printStackTrace();
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}

private String getTemplateUrlFromRequest(HttpServletRequest request) {
if (externalTemplatesEnabled) {
return request.getHeader("template").toString();
} else {
return null;
private String getTemplateUrlFromRequest(HttpServletRequest request, String entityName) {
if (externalTemplatesEnabled && !StringUtils.isEmpty(request.getHeader(Template))) {
return request.getHeader(Template);
}
if (definitionsManager.getCertificateTemplates(entityName).size() > 0 && !StringUtils.isEmpty(request.getHeader(TemplateKey))) {
String templateUri = definitionsManager.getCertificateTemplates(entityName).getOrDefault(request.getHeader(TemplateKey), null);
if (!StringUtils.isEmpty(templateUri)) {
try {
Did did = Did.parse(templateUri);
if (did.getMethod().equals(PATH)) {
return fileStorageService.getSignedUrl(did.getMethodIdentifier());
} else if (did.getMethod().equals(URL)) {
return did.getMethodIdentifier();
}
} catch (Exception e) {
logger.error("Exception while parsing certificate templates DID urls", e);
return null;
}
}

}
return null;
}

@RequestMapping(value = "/api/v1/{entityName}/{entityId}", method = RequestMethod.GET)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ public JsonNode read(String osid) throws Exception {
return readInternal(rootVertex);
}

JsonNode readInternal(Vertex rootVertex) throws Exception {
public JsonNode readInternal(Vertex rootVertex) throws Exception {
if (null == rootVertex) {
throw new RecordNotFoundException("Invalid id");
}
Expand Down
Loading

0 comments on commit 1f1dd9d

Please sign in to comment.