Skip to content
Snippets Groups Projects
Commit c0b440b6 authored by Brandt Beal's avatar Brandt Beal
Browse files

Merge branch 'trusted-aws' into 'master'

Incorporate AWS Integration Tests

See merge request !5
parents cbfd04af c57514cf
No related branches found
No related tags found
1 merge request!5Incorporate AWS Integration Tests
Pipeline #2355 passed
Showing
with 204 additions and 233 deletions
......@@ -24,8 +24,8 @@ public class IndexCacheImpl implements IIndexCache<String, Boolean>, AutoCloseab
private RedisCache<String, Boolean> cache;
public IndexCacheImpl(@Value("${aws.elasticache.cluster.index.endpoint}") final String REDIS_SEARCH_HOST,
@Value("${aws.elasticache.cluster.index.port}") final String REDIS_SEARCH_PORT,
public IndexCacheImpl(@Value("${aws.elasticache.cluster.endpoint}") final String REDIS_SEARCH_HOST,
@Value("${aws.elasticache.cluster.port}") final String REDIS_SEARCH_PORT,
@Value("${aws.elasticache.cluster.index.expiration}") final String INDEX_CACHE_EXPIRATION) {
cache = new RedisCache<>(REDIS_SEARCH_HOST, Integer.parseInt(REDIS_SEARCH_PORT),
Integer.parseInt(INDEX_CACHE_EXPIRATION) * 60, String.class, Boolean.class);
......
......@@ -24,8 +24,8 @@ public class SchemaCacheImpl implements ISchemaCache<String, String>, AutoClosea
private RedisCache<String, String> cache;
public SchemaCacheImpl(@Value("${aws.elasticache.cluster.schema.endpoint}") final String REDIS_SEARCH_HOST,
@Value("${aws.elasticache.cluster.schema.port}") final String REDIS_SEARCH_PORT,
public SchemaCacheImpl(@Value("${aws.elasticache.cluster.endpoint}") final String REDIS_SEARCH_HOST,
@Value("${aws.elasticache.cluster.port}") final String REDIS_SEARCH_PORT,
@Value("${aws.elasticache.cluster.schema.expiration}") final String SCHEMA_CACHE_EXPIRATION) {
cache = new RedisCache<>(REDIS_SEARCH_HOST, Integer.parseInt(REDIS_SEARCH_PORT),
Integer.parseInt(SCHEMA_CACHE_EXPIRATION) * 60, String.class, String.class);
......
// Copyright © Amazon Web Services
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.opengroup.osdu.indexer.aws.di;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.core.common.entitlements.IEntitlementsFactory;
import org.opengroup.osdu.core.common.entitlements.IEntitlementsService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Component
@Primary
public class EntitlementsFactoryImpl implements IEntitlementsFactory {
@Value("${aws.lambda.get-groups-function-name}")
private String getGroupsFunctionName;
@Override
public IEntitlementsService create(DpsHeaders headers) {
EntitlementsServiceImpl service = new EntitlementsServiceImpl(headers);
service.setEntitlementsServiceHelper(getGroupsFunctionName);
return service;
}
}
// Copyright © Amazon Web Services
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.opengroup.osdu.indexer.aws.di;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.lambda.invoke.LambdaFunctionException;
import com.amazonaws.services.lambda.invoke.LambdaSerializationException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.opengroup.osdu.core.common.model.entitlements.*;
import org.opengroup.osdu.core.common.model.entitlements.MemberInfo;
import org.opengroup.osdu.core.common.model.entitlements.Members;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.core.common.entitlements.IEntitlementsService;
import org.opengroup.osdu.core.aws.entitlements.*;
import org.opengroup.osdu.core.common.http.HttpResponse;
import org.opengroup.osdu.core.common.model.http.AppException;
import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpStatus;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import javax.inject.Inject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class EntitlementsServiceImpl implements IEntitlementsService {
private DpsHeaders dpsHeaders;
private EntitlementsServiceHelper entitlementsServiceHelper;
private final static String ACCESS_DENIED = "Access denied";
private final static String ACCESS_DENIED_MSG = "The user is not authorized to perform this action";
@Inject
@Lazy
private JaxRsDpsLog jaxRsDpsLog;
public EntitlementsServiceImpl(DpsHeaders headers){
this.dpsHeaders = headers;
}
public void setEntitlementsServiceHelper(String getGroupsFunctionName){
entitlementsServiceHelper = new EntitlementsServiceHelper(Regions.US_EAST_1, getGroupsFunctionName);
}
@Override
public MemberInfo addMember(GroupEmail groupEmail, MemberInfo memberInfo) throws EntitlementsException {
throw new NotImplementedException();
}
@Override
public Members getMembers(GroupEmail groupEmail, GetMembers getMembers) throws EntitlementsException {
throw new NotImplementedException();
}
@Override
public Groups getGroups() throws EntitlementsException {
Groups groups;
GroupsRequest request = entitlementsServiceHelper.constructRequest(this.dpsHeaders.getHeaders());
try{
GroupsResult groupsResult = entitlementsServiceHelper.getGroups(request);
groups = getGroupsFromResult(groupsResult);
} catch (JsonProcessingException e) {
throw new EntitlementsException(e.getMessage(), new HttpResponse());
} catch (LambdaFunctionException e){
throw new EntitlementsException(e.getMessage(), new HttpResponse());
} catch (LambdaSerializationException e){
throw new EntitlementsException(e.getMessage(), new HttpResponse());
} catch (IOException e){
throw new EntitlementsException(e.getMessage(), new HttpResponse());
}
return groups;
}
@Override
public GroupInfo createGroup(CreateGroup createGroup) throws EntitlementsException {
throw new NotImplementedException();
}
@Override
public void deleteMember(String s, String s1) throws EntitlementsException {
throw new NotImplementedException();
}
@Override
public Groups authorizeAny(String... strings) throws EntitlementsException {
throw new NotImplementedException();
}
@Override
public void authenticate() throws EntitlementsException {
throw new NotImplementedException();
}
private Groups getGroupsFromResult(GroupsResult result) throws EntitlementsException, IOException {
ObjectMapper mapper = new ObjectMapper();
Groups groups = new Groups();
if(result.statusCode == HttpStatus.OK.value()) {
TypeReference<List<GroupInfoRaw>> mapType = new TypeReference<List<GroupInfoRaw>>() {};
List<GroupInfoRaw> groupInfosRaw = mapper.readValue(result.body, mapType);
List<GroupInfo> groupInfos = new ArrayList<>();
for(GroupInfoRaw groupInfoRaw : groupInfosRaw){
GroupInfo groupInfo = new GroupInfo();
groupInfo.setDescription(groupInfoRaw.groupDescription);
groupInfo.setEmail(groupInfoRaw.groupEmail);
groupInfo.setName(groupInfoRaw.groupName);
groupInfos.add(groupInfo);
}
groups.setDesId(result.headers.get(RequestKeys.USER_HEADER_KEY));
groups.setMemberEmail(result.headers.get(RequestKeys.USER_HEADER_KEY));
groups.setGroups(groupInfos);
} else {
if(result.statusCode == HttpStatus.UNAUTHORIZED.value()){
throw new AppException(HttpStatus.FORBIDDEN.value(), ACCESS_DENIED, ACCESS_DENIED_MSG);
} else {
throw new EntitlementsException(String.format("Getting groups for user returned %s status code",
result.statusCode), new HttpResponse());
}
}
return groups;
}
}
......@@ -14,17 +14,19 @@
package org.opengroup.osdu.indexer.aws.persistence;
import org.opengroup.osdu.core.aws.ssm.ParameterStorePropertySource;
import org.opengroup.osdu.core.aws.ssm.SSMConfig;
import org.opengroup.osdu.core.common.model.search.ClusterSettings;
import org.opengroup.osdu.core.common.model.tenant.TenantInfo;
import org.opengroup.osdu.core.common.provider.interfaces.IElasticRepository;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class ElasticRepositoryImpl implements IElasticRepository {
// TODO: Will need to be implemented later
@Value("${aws.es.host}")
String host;
......@@ -33,6 +35,27 @@ public class ElasticRepositoryImpl implements IElasticRepository {
String userNameAndPassword = "testing";
@Value("${aws.elasticsearch.port}")
String portParameter;
@Value("${aws.elasticsearch.host}")
String hostParameter;
@Value("${aws.ssm}")
String ssmEnabledString;
private ParameterStorePropertySource ssm;
@PostConstruct
private void postConstruct() {
if( Boolean.parseBoolean(ssmEnabledString)) {
SSMConfig ssmConfig = new SSMConfig();
ssm = ssmConfig.amazonSSM();
host = ssm.getProperty(hostParameter).toString();
port = Integer.parseInt(ssm.getProperty(portParameter).toString());
}
}
@Override
public ClusterSettings getElasticClusterSettings(TenantInfo tenantInfo) {
return new ClusterSettings(host, port, userNameAndPassword);
......
......@@ -17,6 +17,8 @@ package org.opengroup.osdu.indexer.aws.publish;
import com.amazonaws.services.sns.model.MessageAttributeValue;
import com.amazonaws.services.sns.model.PublishRequest;
import com.amazonaws.services.sns.AmazonSNS;
import org.opengroup.osdu.core.aws.ssm.ParameterStorePropertySource;
import org.opengroup.osdu.core.aws.ssm.SSMConfig;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.core.aws.sns.AmazonSNSConfig;
import org.opengroup.osdu.core.aws.sns.PublishRequestBuilder;
......@@ -34,16 +36,24 @@ public class PublisherImpl implements IPublisher {
AmazonSNS snsClient;
@Value("${aws.sns.arn}")
private ParameterStorePropertySource ssm;
private String amazonSNSTopic;
@Value("${aws.sns.region}")
@Value("${aws.region}")
private String amazonSNSRegion;
@Value("${aws.indexer.sns.topic.arn}")
private String parameter;
@Inject
public void init(){
AmazonSNSConfig snsConfig = new AmazonSNSConfig(amazonSNSRegion);
snsClient = snsConfig.AmazonSNS();
SSMConfig ssmConfig = new SSMConfig();
ssm = ssmConfig.amazonSSM();
amazonSNSTopic = ssm.getProperty(parameter).toString();
}
public void publishStatusChangedTagsToTopic(DpsHeaders headers, JobStatus indexerBatchStatus) throws Exception
......
......@@ -21,6 +21,8 @@ import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.model.SendMessageRequest;
import com.google.gson.Gson;
import org.opengroup.osdu.core.aws.sns.AmazonSNSConfig;
import org.opengroup.osdu.core.aws.ssm.ParameterStorePropertySource;
import org.opengroup.osdu.core.aws.ssm.SSMConfig;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.core.aws.sqs.AmazonSQSConfig;
import org.opengroup.osdu.core.common.model.search.RecordChangedMessages;
......@@ -39,21 +41,29 @@ public class IndexerQueueTaskBuilderAws extends IndexerQueueTaskBuilder {
private AmazonSNS snsClient;
@Value("${aws.region}")
private String region;
private ParameterStorePropertySource ssm;
@Value("${aws.sns.storage.arn}")
private String amazonSNSTopic;
private String retryString = "retry";
private Gson gson;
@Value("${aws.region}")
private String region;
@Value("${aws.storage.sns.topic.arn}")
String parameter;
@Inject
public void init() {
AmazonSNSConfig config = new AmazonSNSConfig(region);
snsClient = config.AmazonSNS();
gson =new Gson();
SSMConfig ssmConfig = new SSMConfig();
ssm = ssmConfig.amazonSSM();
amazonSNSTopic = ssm.getProperty(parameter).toString();
}
@Override
......
LOG_PREFIX=indexer
server.servlet.contextPath=/api/indexer/v2/
logging.level.org.springframework.web=DEBUG
logging.level.org.springframework.web=${LOG_LEVEL}
server.port=${APPLICATION_PORT}
JAVA_HEAP_OPTS=-Xms${JAVA_HEAP_MEMORY}M -Xmx${JAVA_HEAP_MEMORY}M
JAVA_GC_OPTS=-XX:+UseG1GC -XX:+UseStringDeduplication -XX:InitiatingHeapOccupancyPercent=45
aws.threads=50
DEFAULT_DATA_COUNTRY=US
CRON_INDEX_CLEANUP_THRESHOLD_DAYS=3
CRON_EMPTY_INDEX_CLEANUP_THRESHOLD_DAYS=7
## AWS DynamoDB configuration
aws.dynamodb.key=kind
aws.dynamodb.table.prefix=${ENVIRONMENT}-
aws.dynamodb.region=${AWS_REGION}
aws.dynamodb.endpoint=dynamodb.${AWS_REGION}.amazonaws.com
## AWS S3 configuration
aws.s3.region=${AWS_REGION}
aws.s3.endpoint=s3.${AWS_REGION}.amazonaws.com
aws.s3.records.bucket-name=${ENVIRONMENT}-${S3_DATA_BUCKET}
aws.s3.max-record-threads=2000
aws.s3.enable-https=true
## AWS SNS configuration
aws.sns.region=${AWS_REGION}
aws.sns.arn=arn:aws:sns:${AWS_REGION}:${AWS_ACCOUNT_ID}:${ENVIRONMENT}-${SNS_TOPIC_NAME}
aws.sns.storage.arn=arn:aws:sns:${AWS_REGION}:${AWS_ACCOUNT_ID}:${SNS_STORAGE_TOPIC_NAME}
## AWS SQS Configuration
aws.sqs.queue=${ENVIRONMENT}-osdu-indexer-queue
# AWS ES configuration
ELASTIC_HOST=""
ELASTIC_PORT=0
aws.es.host=${ELASTIC_HOST}
aws.es.port=${ELASTIC_PORT}
aws.es.userNameAndPassword=notused
......@@ -41,26 +20,34 @@ aws.es.serviceName=es
GAE_SERVICE=indexer
# TODO This needs to be changed so it snot hard
STORAGE_SCHEMA_HOST=https://${STORAGE_HOST}/api/storage/v2/schemas
STORAGE_QUERY_RECORD_HOST=https://${STORAGE_HOST}/api/storage/v2/query/records
STORAGE_QUERY_RECORD_FOR_CONVERSION_HOST=https://${STORAGE_HOST}/api/storage/v2/query/records:batch
STORAGE_SCHEMA_HOST=${STORAGE_HOST}/api/storage/v2/schemas
STORAGE_QUERY_RECORD_HOST=${STORAGE_HOST}/api/storage/v2/query/records
STORAGE_QUERY_RECORD_FOR_CONVERSION_HOST=${STORAGE_HOST}/api/storage/v2/query/records:batch
STORAGE_RECORDS_BATCH_SIZE=20
INDEXER_QUEUE_HOST=http://sqs.${AWS_REGION}.amazonaws.com/${AWS_ACCOUNT_ID}/${ENVIRONMENT}-osdu-indexer-queue
INDEXER_QUEUE_HOST=""
## AWS ElastiCache configuration
aws.elasticache.cluster.index.endpoint=${CACHE_CLUSTER_INDEX_ENDPOINT}
aws.elasticache.cluster.index.port=${CACHE_CLUSTER_INDEX_PORT}
aws.elasticache.cluster.schema.endpoint=${CACHE_CLUSTER_SCHEMA_ENDPOINT}
aws.elasticache.cluster.schema.port=${CACHE_CLUSTER_SCHEMA_PORT}
aws.elasticache.cluster.endpoint=${CACHE_CLUSTER_ENDPOINT}
aws.elasticache.cluster.port=${CACHE_CLUSTER_PORT}
## Cache Settings
aws.elasticache.cluster.index.expiration=60
aws.elasticache.cluster.schema.expiration=60
# Maximum size of cache value
MAX_CACHE_VALUE_SIZE=1000
## AWS Lambda configuration
aws.lambda.get-groups-function-name=${ENVIRONMENT}-os-entitlements-GroupsFunction
\ No newline at end of file
aws.lambda.get-groups-function-name=${ENVIRONMENT}-os-entitlements-GroupsFunction
## Default DynamoDB Settings
aws.dynamodb.table.prefix=${ENVIRONMENT}-
aws.dynamodb.endpoint=dynamodb.${AWS_REGION}.amazonaws.com
aws.ssm=${SSM_ENABLED}
aws.ssm.prefix=/osdu/${ENVIRONMENT}
aws.elasticsearch.host=${aws.ssm.prefix}/elastic-search/end-point
aws.elasticsearch.port=${aws.ssm.prefix}/elastic-search/end-point-port
aws.indexer.sns.topic.arn=${aws.ssm.prefix}/indexer/indexer-sns-topic-arn
aws.storage.sns.topic.arn=${aws.ssm.prefix}/storage/storage-sns-topic-arn
......@@ -62,7 +62,7 @@
<dependency>
<groupId>org.opengroup.osdu.core.aws</groupId>
<artifactId>os-core-lib-aws</artifactId>
<version>0.0.10</version>
<version>0.2.0</version>
</dependency>
<!-- Testing -->
......@@ -149,13 +149,4 @@
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
......@@ -16,6 +16,7 @@ package org.opengroup.osdu.step_definitions.index.record;
import lombok.extern.java.Log;
import org.opengroup.osdu.common.RecordSteps;
import org.opengroup.osdu.core.common.model.legal.Legal;
import org.opengroup.osdu.util.AWSHTTPClient;
import cucumber.api.Scenario;
......@@ -25,22 +26,53 @@ import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import org.opengroup.osdu.util.ElasticUtilsAws;
import org.opengroup.osdu.util.LegalTagUtilsAws;
import java.util.HashSet;
import java.util.Set;
import static org.opengroup.osdu.util.Config.getLegalTag;
import static org.opengroup.osdu.util.Config.getOtherRelevantDataCountries;
@Log
public class Steps extends RecordSteps {
protected LegalTagUtilsAws legalTagUtils;
private String legalTagName;
public Steps() {
super(new AWSHTTPClient(), new ElasticUtilsAws());
}
@Before
public void before(Scenario scenario) {
public void before(Scenario scenario) throws Exception {
this.scenario = scenario;
this.httpClient = new AWSHTTPClient();
legalTagUtils = new LegalTagUtilsAws(this.httpClient);
this.legalTagName = this.legalTagUtils.createRandomName();
this.legalTagUtils.create(this.legalTagName);
}
@Override
public void tearDown() {
super.tearDown();
this.legalTagUtils.delete(this.legalTagName);
}
@Override
protected Legal generateLegalTag() {
Legal legal = new Legal();
Set<String> legalTags = new HashSet<>();
legalTags.add(this.legalTagName);
legal.setLegaltags(legalTags);
Set<String> otherRelevantCountries = new HashSet<>();
otherRelevantCountries.add(getOtherRelevantDataCountries());
legal.setOtherRelevantDataCountries(otherRelevantCountries);
return legal;
}
@Given("^the schema is created with the following kind$")
public void the_schema_is_created_with_the_following_kind(DataTable dataTable) {
public void the_schema_is_created_with_the_following_kind(DataTable dataTable){
super.the_schema_is_created_with_the_following_kind(dataTable);
}
......
......@@ -28,6 +28,7 @@ public class ElasticUtilsAws extends ElasticUtils {
@Override
public RestClientBuilder createClientBuilder(String host, String usernameAndPassword, int port) {
port = Integer.parseInt(System.getProperty("ELASTIC_PORT", System.getenv("ELASTIC_PORT")));
RestClientBuilder builder = RestClient.builder(new HttpHost(host, port, "https"));
builder.setRequestConfigCallback(requestConfigBuilder -> requestConfigBuilder.setConnectTimeout(REST_CLIENT_CONNECT_TIMEOUT)
.setSocketTimeout(REST_CLIENT_SOCKET_TIMEOUT));
......
// Copyright 2017-2019, Schlumberger
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.opengroup.osdu.util;
import static org.junit.Assert.assertEquals;
import org.apache.http.HttpStatus;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.sun.jersey.api.client.ClientResponse;
import javax.ws.rs.HttpMethod;
public class LegalTagUtilsAws {
private HTTPClient httpClient;
public LegalTagUtilsAws(HTTPClient httpClient) {
this.httpClient = httpClient;
}
public String createRandomName() {
return Config.getDataPartitionIdTenant1() + "-" + System.currentTimeMillis();
}
public ClientResponse create(String legalTagName) throws Exception {
return this.create("US", legalTagName, "2099-01-25", "Public Domain Data");
}
protected ClientResponse create(String countryOfOrigin, String name, String expDate, String dataType)
throws Exception {
String body = getBody(countryOfOrigin, name, expDate, dataType);
ClientResponse response = this.httpClient.send(HttpMethod.POST, String.format("%s%s",getLegalUrl(), "legaltags"), body, httpClient.getCommonHeader(), httpClient.getAccessToken());
assertEquals(HttpStatus.SC_CREATED, response.getStatus());
Thread.sleep(100);
return response;
}
public ClientResponse delete(String legalTagName) {
return this.httpClient.send(HttpMethod.DELETE ,getLegalUrl(), "legaltags/" + legalTagName,httpClient.getCommonHeader(), httpClient.getAccessToken());
}
protected static String getLegalUrl() {
String legalUrl = System.getProperty("LEGAL_URL", System.getenv("LEGAL_URL"));
if (legalUrl == null || legalUrl.contains("-null")) {
legalUrl = "https://os-legal-dot-opendes.appspot.com/api/legal/v1/";
}
return legalUrl;
}
protected static String getBody(String countryOfOrigin, String name, String expDate, String dataType) {
JsonArray coo = new JsonArray();
coo.add(countryOfOrigin);
JsonObject properties = new JsonObject();
properties.add("countryOfOrigin", coo);
properties.addProperty("contractId", "A1234");
properties.addProperty("expirationDate", expDate);
properties.addProperty("dataType", dataType);
properties.addProperty("originator", "MyCompany");
properties.addProperty("securityClassification", "Public");
properties.addProperty("exportClassification", "EAR99");
properties.addProperty("personalData", "No Personal Data");
JsonObject tag = new JsonObject();
tag.addProperty("name", name);
tag.addProperty("description", "test for " + name);
tag.add("properties", properties);
return tag.toString();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<root level="INFO" />
<logger name="org.springframework" level="INFO"/>
</configuration>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment