Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Code snippet configuration #2509

Merged
merged 23 commits into from
Jul 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
bf11d9f
Send full ApiInfos to UI
CarsonCook Jul 15, 2022
4e01c00
Fix unit tests
CarsonCook Jul 15, 2022
e2e902f
WIP - work on mapping code snippets to ApiInfo
taban03 Jul 18, 2022
a56a47e
Add missing class
taban03 Jul 18, 2022
ad42536
Use object mapper to parse apiinfo
CarsonCook Jul 18, 2022
6c4d3e2
Deserialize one code block
CarsonCook Jul 18, 2022
2407216
Convert map to map of list object in order to avoid replacing of valu…
taban03 Jul 19, 2022
79de3ec
Support multiple codesnippet entries
CarsonCook Jul 19, 2022
5aec173
Improve codesnippet testing
CarsonCook Jul 19, 2022
bcd4450
Suppress unchecked warnings
CarsonCook Jul 19, 2022
a6392b0
Propagate codesnippet config to UI
CarsonCook Jul 19, 2022
68ee491
Add unit test
CarsonCook Jul 19, 2022
aedea1d
Add ApiInfo integration test
CarsonCook Jul 19, 2022
efaa4d3
Remove console.log
CarsonCook Jul 20, 2022
879ea96
Merge branch 'v2.x.x' of github.com:zowe/api-layer into apiml/GH2385/…
CarsonCook Jul 20, 2022
583fefc
Fix integration test
CarsonCook Jul 20, 2022
7443357
Merge branch 'v2.x.x' into apiml/GH2385/customized-code-snippets
CarsonCook Jul 20, 2022
a1f345f
Fix code smells
CarsonCook Jul 20, 2022
7ef2d42
Merge branch 'apiml/GH2385/customized-code-snippets' of github.com:zo…
CarsonCook Jul 20, 2022
cd47754
Fix code smell
CarsonCook Jul 20, 2022
c1aa9b0
Remove unused message
CarsonCook Jul 22, 2022
70992bf
Merge branch 'v2.x.x' of github.com:zowe/api-layer into apiml/GH2385/…
CarsonCook Jul 22, 2022
942b156
Merge branch 'v2.x.x' into apiml/GH2385/customized-code-snippets
taban03 Jul 22, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.zowe.apiml.config.ApiInfo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

Expand Down Expand Up @@ -63,11 +65,8 @@ public class APIService implements Serializable {
@Schema(description = "The SSO support for all instances")
private boolean ssoAllInstances;

@Schema(description = "The API ID for this service")
private Map<String, String> apiId;

@Schema(description = "The Gateway URLs used within this service")
private Map<String, String> gatewayUrls;
@Schema(description = "The API information for each API ID for this service")
private Map<String, ApiInfo> apis = new HashMap<>(); // NOSONAR

private List<String> instances = new ArrayList<>();

Expand All @@ -77,7 +76,7 @@ private APIService(String serviceId) {
}

public static class Builder {
private APIService apiService;
private final APIService apiService;

public Builder(String serviceId) {
apiService = new APIService(serviceId);
Expand Down Expand Up @@ -129,18 +128,13 @@ public Builder sso(boolean sso) {
return this;
}

public Builder apiId(Map<String, String> apiId) {
apiService.apiId = apiId;
return this;
}

public Builder gatewayUrls(Map<String, String> gatewayUrls) {
apiService.gatewayUrls = gatewayUrls;
public Builder instanceId(String id) {
apiService.instances.add(id);
return this;
}

public Builder instanceId(String id) {
apiService.instances.add(id);
public Builder apis(Map<String, ApiInfo> apis) {
apiService.apis = apis;
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@

import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;
import static org.zowe.apiml.constants.EurekaMetadataDefinition.*;
Expand All @@ -43,6 +42,8 @@
@Service
public class CachedProductFamilyService {

private static final String DEFAULT_APIINFO_KEY = "default";

@InjectApimlLogger
private final ApimlLogger apimlLog = ApimlLogger.empty();

Expand Down Expand Up @@ -130,7 +131,7 @@ public APIContainer saveContainerFromInstance(String productFamilyId, InstanceIn
} else {
Set<APIService> apiServices = container.getServices();
APIService service = createAPIServiceFromInstance(instanceInfo);

// Verify whether already exists
if (apiServices.contains(service)) {
apiServices.stream()
Expand All @@ -139,7 +140,7 @@ public APIContainer saveContainerFromInstance(String productFamilyId, InstanceIn
if (!existingService.getInstances().contains(instanceInfo.getInstanceId())) {
existingService.getInstances().add(instanceInfo.getInstanceId());
}
}); // If the instance is in list, do nothing otherwise
}); // If the instance is in list, do nothing otherwise
} else {
apiServices.add(service);
}
Expand All @@ -166,7 +167,7 @@ public APIContainer saveContainerFromInstance(String productFamilyId, InstanceIn
* 1) it will remove the whole APIContainer (Tile) if there is no instance of any service remaining
* 2) Remove the service from the containe if there is no instance of service remaining
* 3) Remove instance from the service
*
*
* @param removedInstanceFamilyId the product family id of the container
* @param removedInstance the service instance
*/
Expand Down Expand Up @@ -219,7 +220,7 @@ public void calculateContainerServiceValues(APIContainer apiContainer) {
boolean isSso = servicesCount > 0;
for (APIService apiService : apiContainer.getServices()) {
if (update(apiService)) {
activeServicesCount ++;
activeServicesCount++;
}
isSso &= apiService.isSsoAllInstances();
}
Expand Down Expand Up @@ -333,22 +334,19 @@ private APIService createAPIServiceFromInstance(InstanceInfo instanceInfo) {

String instanceHomePage = getInstanceHomePageUrl(instanceInfo);
String apiBasePath = getApiBasePath(instanceInfo);
Map<String, String> apiId = new HashMap<>();
Map<String, String> gatewayUrls = new HashMap<>();
Map<String, ApiInfo> apiInfoById = new HashMap<>();

try {
apiId = metadataParser.parseApiInfo(instanceInfo.getMetadata()).stream().filter(apiInfo -> apiInfo.getApiId() != null).collect(
Collectors.toMap(
apiInfo -> (apiInfo.getMajorVersion() < 0) ? "default" : apiInfo.getApiId() + " v" + apiInfo.getVersion(),
ApiInfo::getApiId
)
);

gatewayUrls = metadataParser.parseApiInfo(instanceInfo.getMetadata()).stream().filter(apiInfo -> apiInfo.getApiId() != null).collect(
Collectors.toMap(
apiInfo -> (apiInfo.getMajorVersion() < 0) ? "default" : apiInfo.getApiId() + " v" + apiInfo.getVersion(),
ApiInfo::getGatewayUrl
)
);
List<ApiInfo> apiInfoList = metadataParser.parseApiInfo(instanceInfo.getMetadata());
apiInfoList.stream().filter(apiInfo -> apiInfo.getApiId() != null).forEach(apiInfo -> {
String id = (apiInfo.getMajorVersion() < 0) ? DEFAULT_APIINFO_KEY : apiInfo.getApiId() + " v" + apiInfo.getVersion();
apiInfoById.put(id, apiInfo);
});

if (!apiInfoById.containsKey(DEFAULT_APIINFO_KEY)) {
ApiInfo defaultApiInfo = apiInfoList.stream().filter(ApiInfo::isDefaultApi).findFirst().orElse(null);
apiInfoById.put(DEFAULT_APIINFO_KEY, defaultApiInfo);
}
} catch (Exception ex) {
log.info("createApiServiceFromInstance#incorrectVersions {}", ex.getMessage());
}
Expand All @@ -361,8 +359,7 @@ private APIService createAPIServiceFromInstance(InstanceInfo instanceInfo) {
.homePageUrl(instanceHomePage)
.basePath(apiBasePath)
.sso(isSso(instanceInfo))
.apiId(apiId)
.gatewayUrls(gatewayUrls)
.apis(apiInfoById)
.instanceId(instanceInfo.getInstanceId())
.build();
}
Expand Down
7 changes: 7 additions & 0 deletions api-catalog-services/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,13 @@ eureka:
version: 1.0.0
gatewayUrl: api/v1
swaggerUrl: https://${apiml.service.hostname}:${apiml.service.port}${apiml.service.contextPath}/v3/api-docs
codeSnippet:
- endpoint: "/greetings"
codeBlock: |
```
System. out. println("Hello, World!");
```
language: java

service:
title: API Catalog
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,15 @@ class WhenAllContainersAreRequested {
@Test
void thenReturnNoContent() {
given(cachedProductFamilyService.getAllContainers()).willReturn(null);

RestAssuredMockMvc.given().
when().
get(pathToContainers).
then().
statusCode(HttpStatus.NO_CONTENT.value());
}
}

@Nested
class WhenSpecificContainerRequested {
@Test
Expand Down Expand Up @@ -103,8 +103,8 @@ void prepareApplications() {
apiVersions = Arrays.asList("1.0.0", "2.0.0");

given(cachedServicesService.getService("service1")).willReturn(service1);
given(cachedApiDocService.getDefaultApiDocForService("service1")).willReturn("service1");
given(cachedApiDocService.getApiVersionsForService("service1")).willReturn(apiVersions);
given(cachedApiDocService.getDefaultApiDocForService("service1")).willReturn("service1");
given(cachedApiDocService.getApiVersionsForService("service1")).willReturn(apiVersions);

given(cachedServicesService.getService("service2")).willReturn(service2);
given(cachedApiDocService.getDefaultApiDocForService("service2")).willReturn("service2");
Expand Down Expand Up @@ -193,7 +193,7 @@ private void assertThereIsOneContainer(ResponseEntity<List<APIContainer>> contai
}
}




// =========================================== Helper Methods ===========================================
Expand All @@ -209,7 +209,7 @@ private List<APIContainer> createContainers() {
.homePageUrl("home")
.basePath("base")
.sso(false)
.apiId(Collections.emptyMap())
.apis(Collections.emptyMap())
.build();
services.add(service);

Expand All @@ -221,7 +221,7 @@ private List<APIContainer> createContainers() {
.homePageUrl("home")
.basePath("base")
.sso(false)
.apiId(Collections.emptyMap())
.apis(Collections.emptyMap())
.build();
services.add(service);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ void prepareInstances() throws URLTransformationException {
metadata.put(SERVICE_DESCRIPTION, "sDescription");
instance = servicesBuilder.createInstance("service1", InstanceInfo.InstanceStatus.UP, metadata);

Map<String, String> updatedMetadata = new HashMap<String, String>();
Map<String, String> updatedMetadata = new HashMap<>();
updatedMetadata.put(CATALOG_ID, "demoapp");
updatedMetadata.put(CATALOG_TITLE, "Title2");
updatedMetadata.put(CATALOG_DESCRIPTION, "Description2");
Expand All @@ -101,7 +101,7 @@ void prepareInstances() throws URLTransformationException {
@Nested
class GivenInstanceIsNotInCache {
@Test
void createNew() throws URLTransformationException {
void createNew() {
APIContainer originalContainer = underTest.saveContainerFromInstance("demoapp", instance);

List<APIContainer> lsContainer = underTest.getRecentlyUpdatedContainers();
Expand All @@ -112,7 +112,7 @@ void createNew() throws URLTransformationException {
@Nested
class GivenInstanceIsInTheCache {
@Test
void update() throws InterruptedException, URLTransformationException {
void update() throws InterruptedException {
APIContainer originalContainer = underTest.saveContainerFromInstance("demoapp", instance);
Calendar createdTimestamp = originalContainer.getLastUpdatedTimestamp();

Expand Down Expand Up @@ -151,7 +151,7 @@ private void assertThatMetadataAreCorrect(APIContainer result, Map<String, Strin
assertThat(result.getDescription(), is(correct.get(CATALOG_DESCRIPTION)));
assertThat(result.getVersion(), is(correct.get(CATALOG_VERSION)));
}
}
}

@Nested
class WhenRemovingService {
Expand All @@ -170,7 +170,7 @@ void prepareExistingInstance() {
metadata.put(SERVICE_TITLE, "sTitle");
metadata.put(SERVICE_DESCRIPTION, "sDescription");
removedInstance = servicesBuilder.createInstance("service1", InstanceInfo.InstanceStatus.UP, metadata);

underTest.saveContainerFromInstance(removedInstanceFamilyId, removedInstance);
}

Expand Down Expand Up @@ -398,11 +398,11 @@ void groupThem() {
underTest.calculateContainerServiceValues(apiContainer);

APIService apiService = apiContainer.getServices().iterator().next();
assertNotNull(apiService.getApiId());
assertEquals(3, apiService.getApiId().size());
assertEquals("api1", apiService.getApiId().get("api1 v1.0.0"));
assertEquals("api2", apiService.getApiId().get("api2 v2"));
assertEquals("api3", apiService.getApiId().get("default"));
assertNotNull(apiService.getApis());
assertEquals(3, apiService.getApis().size());
assertNotNull(apiService.getApis().get("api1 v1.0.0"));
assertNotNull(apiService.getApis().get("api2 v2"));
assertNotNull(apiService.getApis().get("default"));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ private List<APIContainer> createContainers() {
.homePageUrl("home")
.basePath("base")
.sso(false)
.apiId(Collections.emptyMap())
.apis(Collections.emptyMap())
.build();
services.add(service);

Expand All @@ -184,7 +184,7 @@ private List<APIContainer> createContainers() {
.homePageUrl("home")
.basePath("base")
.sso(false)
.apiId(Collections.emptyMap())
.apis(Collections.emptyMap())
.build();
services.add(service);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ private APIService addApiService(String serviceId,
.homePageUrl("home")
.basePath("base")
.sso(false)
.apiId(Collections.emptyMap())
.apis(Collections.emptyMap())
.build();
services.add(service);
allServices.add(service);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ export default class InstanceInfo extends Component {
render() {
const { selectedService, selectedVersion } = this.props;

const apiId =
selectedService.apiId[selectedVersion || selectedService.defaultApiVersion] ||
selectedService.apiId.default;
const apiInfo =
selectedService.apis[selectedVersion || selectedService.defaultApiVersion] || selectedService.apis.default;
const { apiId } = apiInfo;
return (
<Shield title="Cannot display information about selected instance">
<div className="apiInfo-item">
Expand All @@ -31,11 +31,7 @@ export default class InstanceInfo extends Component {
</Tooltip>
</div>
<div className="apiInfo-item">
<Tooltip
key={selectedService.apiId}
title="API IDs of the APIs that are provided by this service"
placement="bottom"
>
<Tooltip title="API IDs of the APIs that are provided by this service" placement="bottom">
<Typography>
{/* eslint-disable-next-line jsx-a11y/label-has-for */}
<label htmlFor="apiid">API ID:</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ const selectedService = {

describe('>>> InstanceInfo component tests', () => {
it('Service with version v1', () => {
selectedService.apiId = {
v1: 'zowe.apiml.gateway',
selectedService.apis = {
v1: { apiId: 'zowe.apiml.gateway' },
};
const selectService = jest.fn();
const instanceInfo = shallow(
Expand All @@ -35,8 +35,8 @@ describe('>>> InstanceInfo component tests', () => {
});

it('No selected version, use defaultApiVersion', () => {
selectedService.apiId = {
v1: 'zowe.apiml.gateway',
selectedService.apis = {
v1: { apiId: 'zowe.apiml.gateway' },
};
selectedService.defaultApiVersion = ['v1'];
const selectService = jest.fn();
Expand All @@ -46,8 +46,8 @@ describe('>>> InstanceInfo component tests', () => {
});

it('No selected version and not set defaultApiVersion use key default', () => {
selectedService.apiId = {
default: 'zowe.apiml.gateway',
selectedService.apis = {
default: { apiId: 'zowe.apiml.gateway' },
};
selectedService.defaultApiVersion = null;
const selectService = jest.fn();
Expand Down
Loading