Skip to content

Commit

Permalink
feat: use latest cockpit connector
Browse files Browse the repository at this point in the history
BREAKING-CHANGE: this implies to use the latest cockpit version and configuration
  • Loading branch information
guillaumelamirand committed Mar 5, 2024
1 parent cc7758b commit 50e4852
Show file tree
Hide file tree
Showing 51 changed files with 1,669 additions and 1,534 deletions.
10 changes: 10 additions & 0 deletions .run/Rest API - JDBC.run.xml
Expand Up @@ -14,6 +14,16 @@
<module name="gravitee-apim-rest-api-standalone-container" />
<option name="VM_PARAMETERS" value="-Dgravitee.home=$ProjectFileDir$/gravitee-apim-rest-api/gravitee-apim-rest-api-standalone/gravitee-apim-rest-api-standalone-distribution/target/distribution" />
<option name="WORKING_DIRECTORY" value="$ProjectFileDir$" />
<extension name="net.ashald.envfile">
<option name="IS_ENABLED" value="false" />
<option name="IS_SUBST" value="false" />
<option name="IS_PATH_MACRO_SUPPORTED" value="false" />
<option name="IS_IGNORE_MISSING_FILES" value="false" />
<option name="IS_ENABLE_EXPERIMENTAL_INTEGRATIONS" value="false" />
<ENTRIES>
<ENTRY IS_ENABLED="true" PARSER="runconfig" IS_EXECUTABLE="false" />
</ENTRIES>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
Expand Down
@@ -1,4 +1,5 @@
// Copyright 2015 The gRPC Authors
//
// Copyright © 2015 The Gravitee team (http://gravitee.io)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -11,6 +12,8 @@
// 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.
//

syntax = "proto3";

option java_multiple_files = true;
Expand Down
@@ -1,4 +1,5 @@
// Copyright 2015 The gRPC Authors
//
// Copyright © 2015 The Gravitee team (http://gravitee.io)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -11,6 +12,8 @@
// 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.
//

syntax = "proto3";

option java_multiple_files = true;
Expand Down
Expand Up @@ -172,16 +172,18 @@ public Response tokenExchange(@QueryParam(value = "token") final String token, @

private Key getPublicKey() throws Exception {
final KeyStore trustStore = loadTrustStore();
final Certificate cert = trustStore.getCertificate(environment.getProperty("cockpit.keystore.key.alias", "cockpit-client"));
final Certificate cert = trustStore.getCertificate(
environment.getProperty("cockpit.connector.ws.ssl.keystore.key.alias", "cockpit-client")
);

return cert.getPublicKey();
}

private KeyStore loadTrustStore() throws Exception {
final KeyStore keystore = KeyStore.getInstance(environment.getProperty("cockpit.keystore.type"));
final KeyStore keystore = KeyStore.getInstance(environment.getProperty("cockpit.connector.ws.ssl.keystore.type"));

try (InputStream is = new File(environment.getProperty("cockpit.keystore.path")).toURI().toURL().openStream()) {
final String password = environment.getProperty("cockpit.keystore.password");
try (InputStream is = new File(environment.getProperty("cockpit.connector.ws.ssl.keystore.path")).toURI().toURL().openStream()) {
final String password = environment.getProperty("cockpit.connector.ws.ssl.keystore.password");
keystore.load(is, null == password ? null : password.toCharArray());
}

Expand Down
Expand Up @@ -15,13 +15,9 @@
*/
package io.gravitee.rest.api.service.cockpit.command;

import io.gravitee.cockpit.api.command.Command;
import io.gravitee.cockpit.api.command.Payload;
import io.gravitee.cockpit.api.command.Reply;
import io.gravitee.cockpit.api.command.bridge.BridgeCommand;
import io.gravitee.cockpit.api.command.bridge.BridgeReply;
import io.gravitee.cockpit.api.command.v1.bridge.BridgeCommand;
import io.gravitee.cockpit.api.command.v1.bridge.BridgeReply;

public interface CockpitCommandService {
BridgeReply send(BridgeCommand command);
<T extends Payload> Reply send(Command<T> command);
}
Expand Up @@ -16,14 +16,8 @@
package io.gravitee.rest.api.service.cockpit.command;

import io.gravitee.cockpit.api.CockpitConnector;
import io.gravitee.cockpit.api.command.Command;
import io.gravitee.cockpit.api.command.CommandStatus;
import io.gravitee.cockpit.api.command.Payload;
import io.gravitee.cockpit.api.command.Reply;
import io.gravitee.cockpit.api.command.bridge.BridgeCommand;
import io.gravitee.cockpit.api.command.bridge.BridgePayload;
import io.gravitee.cockpit.api.command.bridge.BridgeReply;
import io.gravitee.cockpit.api.command.bridge.BridgeSimpleReply;
import io.gravitee.cockpit.api.command.v1.bridge.BridgeCommand;
import io.gravitee.cockpit.api.command.v1.bridge.BridgeReply;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

Expand All @@ -41,20 +35,10 @@ public CockpitCommandServiceImpl(

@Override
public BridgeReply send(BridgeCommand command) {
return (BridgeReply) send((Command<BridgePayload>) command);
}

@Override
public <T extends Payload> Reply send(Command<T> command) {
return cockpitConnector
.sendCommand(command)
.onErrorReturn(error ->
new BridgeSimpleReply(
command.getId(),
CommandStatus.ERROR,
error.getMessage() != null ? error.getMessage() : error.toString()
)
)
.onErrorReturn(error -> new BridgeReply(command.getId(), error.getMessage() != null ? error.getMessage() : error.toString()))
.cast(BridgeReply.class)
.blockingGet();
}
}
@@ -0,0 +1,64 @@
/*
* Copyright © 2015 The Gravitee team (http://gravitee.io)
*
* 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 io.gravitee.rest.api.service.cockpit.command;

import io.gravitee.exchange.api.command.Command;
import io.gravitee.exchange.api.command.CommandAdapter;
import io.gravitee.exchange.api.command.CommandHandler;
import io.gravitee.exchange.api.command.Reply;
import io.gravitee.exchange.api.command.ReplyAdapter;
import io.gravitee.exchange.api.connector.ConnectorCommandContext;
import io.gravitee.exchange.api.connector.ConnectorCommandHandlersFactory;
import io.gravitee.exchange.api.websocket.protocol.ProtocolVersion;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
* @author Guillaume LAMIRAND (guillaume.lamirand at graviteesource.com)
* @author GraviteeSource Team
*/
@Component("cockpitConnectorCommandHandlersFactory")
@RequiredArgsConstructor
public class CockpitConnectorCommandHandlersFactory implements ConnectorCommandHandlersFactory {

private final List<CommandHandler<? extends Command<?>, ? extends Reply<?>>> commandHandlers;
private final List<CommandAdapter<? extends Command<?>, ? extends Command<?>, ? extends Reply<?>>> commandAdapters;
private final List<ReplyAdapter<? extends Reply<?>, ? extends Reply<?>>> replyAdapters;

@Override
public List<CommandHandler<? extends Command<?>, ? extends Reply<?>>> buildCommandHandlers(
final ConnectorCommandContext connectorCommandContext
) {
return commandHandlers;
}

@Override
public List<CommandAdapter<? extends Command<?>, ? extends Command<?>, ? extends Reply<?>>> buildCommandAdapters(
final ConnectorCommandContext connectorCommandContext,
final ProtocolVersion protocolVersion
) {
return commandAdapters;
}

@Override
public List<ReplyAdapter<? extends Reply<?>, ? extends Reply<?>>> buildReplyAdapters(
final ConnectorCommandContext connectorCommandContext,
final ProtocolVersion protocolVersion
) {
return replyAdapters;
}
}
@@ -0,0 +1,158 @@
/*
* Copyright © 2015 The Gravitee team (http://gravitee.io)
*
* 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 io.gravitee.rest.api.service.cockpit.command.adapter;

import io.gravitee.apim.core.cockpit.query_service.CockpitAccessService;
import io.gravitee.apim.core.installation.domain_service.InstallationTypeDomainService;
import io.gravitee.apim.core.installation.model.InstallationType;
import io.gravitee.cockpit.api.CockpitConnector;
import io.gravitee.cockpit.api.command.model.accesspoint.AccessPoint;
import io.gravitee.cockpit.api.command.v1.CockpitCommandType;
import io.gravitee.cockpit.api.command.v1.hello.HelloCommand;
import io.gravitee.cockpit.api.command.v1.hello.HelloCommandPayload;
import io.gravitee.cockpit.api.command.v1.hello.HelloReply;
import io.gravitee.cockpit.api.command.v1.installation.AdditionalInfoConstants;
import io.gravitee.common.util.Version;
import io.gravitee.exchange.api.command.CommandAdapter;
import io.gravitee.node.api.Node;
import io.gravitee.plugin.core.api.PluginRegistry;
import io.gravitee.rest.api.service.InstallationService;
import io.gravitee.rest.api.service.common.GraviteeContext;
import io.reactivex.rxjava3.core.Single;
import jakarta.annotation.PostConstruct;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

/**
* @author Florent CHAMFROY (florent.chamfroy at graviteesource.com)
* @author GraviteeSource Team
*/
@Component
@RequiredArgsConstructor
@Slf4j
public class HelloCommandAdapter implements CommandAdapter<io.gravitee.exchange.api.command.hello.HelloCommand, HelloCommand, HelloReply> {

private static final String PATH_SUFFIX = "/";

@Value("${installation.api.url:http://localhost:8083}")
private String apiURL;

@Value("${installation.api.proxyPath.management:${http.api.management.entrypoint:${http.api.entrypoint:/}management}}")
private String managementProxyPath;

@Value("${cockpit.auth.path:/auth/cockpit?token={token}}")
private String authPath;

@Value("${cockpit.trial:false}")
private boolean cockpitTrial;

private final Node node;
private final InstallationService installationService;
private final InstallationTypeDomainService installationTypeDomainService;
private final CockpitAccessService cockpitAccessService;
private final PluginRegistry pluginRegistry;
private String buildAuthPath;

@PostConstruct
public void afterPropertiesSet() {
StringBuilder authPathBuilder = new StringBuilder(managementProxyPath);
if (managementProxyPath.endsWith(PATH_SUFFIX) && authPath.startsWith(PATH_SUFFIX)) {
authPathBuilder.append(authPath.substring(1));
} else if (
(managementProxyPath.endsWith(PATH_SUFFIX) && !authPath.startsWith(PATH_SUFFIX)) ||
(!managementProxyPath.endsWith(PATH_SUFFIX) && authPath.startsWith(PATH_SUFFIX))
) {
authPathBuilder.append(authPath);
} else if (!managementProxyPath.endsWith(PATH_SUFFIX) && !authPath.startsWith(PATH_SUFFIX)) {
authPathBuilder.append(managementProxyPath).append(PATH_SUFFIX).append(authPath);
}
this.buildAuthPath = authPathBuilder.toString();
}

@Override
public String supportType() {
return CockpitCommandType.HELLO.name();
}

@Override
public Single<HelloCommand> adapt(final io.gravitee.exchange.api.command.hello.HelloCommand command) {
return Single
.fromCallable(installationService::getOrInitialize)
.map(installation -> {
InstallationType installationType = installationTypeDomainService.get();

HelloCommandPayload.HelloCommandPayloadBuilder<?, ?> payloadBuilder = HelloCommandPayload
.builder()
.node(
io.gravitee.cockpit.api.command.model.Node
.builder()
.application(node.application())
.installationId(installation.getId())
.hostname(node.hostname())
.version(Version.RUNTIME_VERSION.MAJOR_VERSION)
.connectorVersion(connectorVersion())
.build()
)
.installationType(installationType.getLabel())
.trial(cockpitTrial)
.defaultOrganizationId(GraviteeContext.getDefaultOrganization())
.defaultEnvironmentId(GraviteeContext.getDefaultEnvironment());
Map<String, String> additionalInformation = new HashMap<>(installation.getAdditionalInformation());
additionalInformation.put(AdditionalInfoConstants.AUTH_PATH, buildAuthPath);
if (installationType == InstallationType.MULTI_TENANT) {
Map<AccessPoint.Type, List<AccessPoint>> accessPointTemplates = new EnumMap<>(AccessPoint.Type.class);
cockpitAccessService
.getAccessPointsTemplate()
.forEach((type, accessPoints) ->
accessPointTemplates.put(
AccessPoint.Type.valueOf(type.name()),
accessPoints
.stream()
.map(accessPoint ->
AccessPoint
.builder()
.host(accessPoint.getHost())
.secured(accessPoint.isSecured())
.target(AccessPoint.Target.valueOf(accessPoint.getTarget().name()))
.build()
)
.toList()
)
);
payloadBuilder.accessPointsTemplate(accessPointTemplates);
} else {
additionalInformation.put(AdditionalInfoConstants.AUTH_BASE_URL, apiURL);
}
payloadBuilder.additionalInformation(additionalInformation);
return new HelloCommand(payloadBuilder.build());
});
}

private String connectorVersion() {
try {
return this.pluginRegistry.get("cockpit", "cockpit-connectors-ws").manifest().version();
} catch (Exception e) {
return "unknown";
}
}
}

0 comments on commit 50e4852

Please sign in to comment.