/* Copyright 2014 Danish Maritime Authority.
*
* 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 net.maritimecloud.portal.resource;
import java.util.List;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import net.maritimecloud.portal.application.ApplicationServiceRegistry;
import static net.maritimecloud.portal.resource.ResourceResolver.resolveOrganizationIdOrFail;
import static net.maritimecloud.portal.resource.ResourceResolver.resolveServiceInstance;
import static net.maritimecloud.portal.resource.ResourceResolver.resolveServiceSpecification;
import net.maritimecloud.common.resource.AbstractCommandResource;
import net.maritimecloud.common.resource.JsonCommandHelper;
import net.maritimecloud.serviceregistry.command.api.*;
import net.maritimecloud.serviceregistry.command.organization.OrganizationId;
import net.maritimecloud.serviceregistry.command.serviceinstance.ChangeServiceInstanceCoverage;
import net.maritimecloud.serviceregistry.command.serviceinstance.ServiceInstanceId;
import net.maritimecloud.serviceregistry.domain.service.AliasGroups;
import net.maritimecloud.serviceregistry.query.AliasRegistryEntry;
import net.maritimecloud.serviceregistry.query.OrganizationEntry;
import net.maritimecloud.serviceregistry.query.ServiceInstanceEntry;
import net.maritimecloud.serviceregistry.query.ServiceSpecificationEntry;
import org.axonframework.commandhandling.gateway.CommandGateway;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author Christoffer Børrild
*/
@Path("/api")
public class OrganizationResource extends AbstractCommandResource {
private static final Logger LOG = LoggerFactory.getLogger(OrganizationResource.class);
@Override
protected CommandGateway commandGateway() {
return ApplicationServiceRegistry.commandGateway();
}
// -------------------------------------------------------
// -------------------------------------------------------
// Commands
// -------------------------------------------------------
// -------------------------------------------------------
@POST
@Consumes(APPLICATION_JSON_CQRS_COMMAND)
@Produces(MediaType.APPLICATION_JSON)
@Path("org")
public void organizationPostCommand(@HeaderParam("Content-type") String contentType, @QueryParam("command") @DefaultValue("") String queryCommandName, String commandJSON) {
LOG.info("Organization POST command");
sendAndWait(contentType, queryCommandName, commandJSON,
CreateOrganization.class
);
}
@PUT
@Consumes(APPLICATION_JSON_CQRS_COMMAND)
@Produces(MediaType.APPLICATION_JSON)
@Path("org/{organizationIdOrAlias}")
public void organizationPutCommand(
@HeaderParam("Content-type") String contentType,
@QueryParam("command") @DefaultValue("") String queryCommandName,
@PathParam("organizationIdOrAlias") String organizationIdOrAlias,
String commandJSON
) {
LOG.info("Organization PUT command");
String organizationId = resolveOrganizationIdOrFail(organizationIdOrAlias);
commandJSON = overwriteIdentity(commandJSON, "organizationId", organizationId);
sendAndWait(contentType, queryCommandName, commandJSON,
ChangeOrganizationNameAndSummary.class,
ChangeOrganizationWebsiteUrl.class,
AddOrganizationAlias.class,
RemoveOrganizationAlias.class
);
}
// ------------------------------------------------------------------------
// MEMBERSHIP
// ------------------------------------------------------------------------
@POST
@Consumes(APPLICATION_JSON_CQRS_COMMAND)
@Produces(MediaType.APPLICATION_JSON)
@Path("org/{organizationIdOrAlias}/member")
public void membershipPostCommand(
@HeaderParam("Content-type") String contentType,
@QueryParam("command") @DefaultValue("") String queryCommandName,
@PathParam("organizationIdOrAlias") String organizationIdOrAlias,
String commandJSON
) {
String organizationId = resolveOrganizationIdOrFail(organizationIdOrAlias);
commandJSON = overwriteIdentity(commandJSON, "organizationId", organizationId);
sendAndWait(contentType, queryCommandName, commandJSON,
InviteUserToOrganization.class,
ApplyForMembershipToOrganization.class
);
}
@PUT
@Consumes(APPLICATION_JSON_CQRS_COMMAND)
@Produces(MediaType.APPLICATION_JSON)
@Path("org/{organizationIdOrAlias}/member")
public void membershipPutCommand(
@HeaderParam("Content-type") String contentType,
@QueryParam("command") @DefaultValue("") String queryCommandName,
@PathParam("organizationIdOrAlias") String organizationIdOrAlias,
String commandJSON
) {
String organizationId = resolveOrganizationIdOrFail(organizationIdOrAlias);
commandJSON = overwriteIdentity(commandJSON, "organizationId", organizationId);
sendAndWait(contentType, queryCommandName, commandJSON,
AcceptUsersMembershipApplication.class,
AcceptMembershipToOrganization.class,
RemoveUserFromOrganization.class
);
}
// ------------------------------------------------------------------------
// SERVICE SPECIFICATIONS
// ------------------------------------------------------------------------
@POST
@Consumes(APPLICATION_JSON_CQRS_COMMAND)
@Produces(MediaType.APPLICATION_JSON)
@Path("org/{organizationIdOrAlias}/ss")
public void serviceSpecificationPostCommand(
@HeaderParam("Content-type") String contentType,
@QueryParam("command") @DefaultValue("") String queryCommandName,
@PathParam("organizationIdOrAlias") String organizationIdOrAlias,
String commandJSON
) {
LOG.info("Service Instance POST command");
String organizationId = resolveOrganizationIdOrFail(organizationIdOrAlias);
commandJSON = overwriteIdentity(commandJSON, "ownerId", organizationId);
sendAndWait(contentType, queryCommandName, commandJSON,
PrepareServiceSpecification.class
);
}
@PUT
@Consumes(APPLICATION_JSON_CQRS_COMMAND)
@Produces(MediaType.APPLICATION_JSON)
@Path("org/{organizationIdOrAlias}/ss/{serviceSpecificationIdOrAlias}")
public void serviceSpecificationPutCommand(
@HeaderParam("Content-type") String contentType,
@QueryParam("command") @DefaultValue("") String queryCommandName,
@PathParam("organizationIdOrAlias") String organizationIdOrAlias,
@PathParam("serviceSpecificationIdOrAlias") String serviceSpecificationIdOrAlias,
String commandJSON
) {
LOG.info("Service Instance PUT command");
ServiceSpecificationEntry serviceSpecification = getServiceSpecificationByAlias(organizationIdOrAlias, serviceSpecificationIdOrAlias);
commandJSON = overwriteIdentity(commandJSON, "serviceSpecificationId", serviceSpecification.getServiceSpecificationId());
sendAndWait(contentType, queryCommandName, commandJSON,
ChangeServiceSpecificationNameAndSummary.class
);
}
// ------------------------------------------------------------------------
// SERVICE INSTANCES
// ------------------------------------------------------------------------
@POST
@Consumes(APPLICATION_JSON_CQRS_COMMAND)
@Produces(MediaType.APPLICATION_JSON)
@Path("org/{organizationIdOrAlias}/si")
public void serviceInstancePostCommand(
@HeaderParam("Content-type") String contentType,
@QueryParam("command") @DefaultValue("") String queryCommandName,
@PathParam("organizationIdOrAlias") String organizationIdOrAlias,
String commandJSON
) {
LOG.info("Service Instance POST command");
String organizationId = resolveOrganizationIdOrFail(organizationIdOrAlias);
commandJSON = overwriteIdentity(commandJSON, "providerId", organizationId);
sendAndWait(contentType, queryCommandName, commandJSON,
ProvideServiceInstance.class
);
}
@PUT
@Consumes(APPLICATION_JSON_CQRS_COMMAND)
@Produces(MediaType.APPLICATION_JSON)
@Path("org/{organizationIdOrAlias}/si/{serviceInstanceIdOrAlias}")
public void serviceInstancePutCommand(
@HeaderParam("Content-type") String contentType,
@QueryParam("command") @DefaultValue("") String queryCommandName,
@PathParam("organizationIdOrAlias") String organizationIdOrAlias,
@PathParam("serviceInstanceIdOrAlias") String serviceInstanceIdOrAlias,
String commandJSON
) {
LOG.info("Service Instance PUT command");
// assert that instance exists and belongs to organization
ServiceInstanceEntry serviceInstance = getServiceInstanceByAlias(organizationIdOrAlias, serviceInstanceIdOrAlias);
// enrich command with mandatory identifiers (those of the path)
// ...
// ( todo: add any missing identifier properties
// need to know which based on commandName !?! )
// rewrite command to contain the identifiers of the path
//System.out.println("commandJSON: "+commandJSON);
commandJSON = overwriteIdentity(commandJSON, "serviceInstanceId", serviceInstance.getServiceInstanceId());
commandJSON = overwriteIdentity(commandJSON, "organizationId", serviceInstance.getProviderId());
commandJSON = overwriteIdentity(commandJSON, "providerId", serviceInstance.getProviderId());
sendAndWait(contentType, queryCommandName, commandJSON,
ChangeServiceInstanceNameAndSummary.class,
ChangeServiceInstanceCoverage.class,
AddServiceInstanceEndpoint.class,
AddServiceInstanceAlias.class,
RemoveServiceInstanceAlias.class,
RemoveServiceInstanceEndpoint.class
);
}
@DELETE
@Consumes(APPLICATION_JSON_CQRS_COMMAND)
@Produces(MediaType.APPLICATION_JSON)
@Path("org/{organizationIdOrAlias}/si/{serviceInstanceIdOrAlias}")
public void serviceInstanceDeleteCommand(
@HeaderParam("Content-type") String contentType,
@QueryParam("command") @DefaultValue("") String queryCommandName,
@PathParam("organizationIdOrAlias") String organizationIdOrAlias,
@PathParam("serviceInstanceIdOrAlias") String serviceInstanceIdOrAlias,
String commandJSON
) {
LOG.info("Service Instance DELETE command");
ServiceInstanceEntry serviceInstance = getServiceInstanceByAlias(organizationIdOrAlias, serviceInstanceIdOrAlias);
commandJSON = overwriteIdentity(commandJSON, "serviceInstanceId", serviceInstance.getServiceInstanceId());
sendAndWait(contentType, queryCommandName, commandJSON,
RemoveServiceInstanceEndpoint.class
);
}
// -------------------------------------------------------
// -------------------------------------------------------
// Queries
// -------------------------------------------------------
// -------------------------------------------------------
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("org")
public Iterable<OrganizationEntry> getOrganizations(
@QueryParam("namePattern") @DefaultValue("") String organizationNamePattern
) {
// TODO: Not sure if this method is ever used!?!
return ApplicationServiceRegistry.organizationQueryRepository().findAll();
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("org/{organizationIdOrAlias}")
public OrganizationEntry getOrganization(@PathParam("organizationIdOrAlias") String organizationIdOrAlias) {
String organizationId = resolveOrganizationIdOrFail(organizationIdOrAlias);
return ApplicationServiceRegistry.organizationQueryRepository().findOne(organizationId);
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("org/{organizationIdOrAlias}/alias")
public List<AliasRegistryEntry> queryOrganizationAliases(
@PathParam("organizationIdOrAlias") String organizationIdOrAlias
) {
String organizationId = resolveOrganizationIdOrFail(organizationIdOrAlias);
return ResourceResolver.queryOrganizationAliases(organizationId);
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("org/{organizationIdOrAlias}/alias/{alias}")
public AliasRegistryEntry getOrganizationAlias(
@PathParam("organizationIdOrAlias") String organizationIdOrAlias,
@PathParam("alias") String alias
) {
final AliasRegistryEntry lookupAlias = lookupAlias(AliasGroups.USERS_AND_ORGANIZATIONS.name(), OrganizationId.class, alias);
return lookupAlias;
}
// ------------------------------------------------------------------------
// SERVICE SPECIFICATIONS
// ------------------------------------------------------------------------
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("org/{organizationIdOrAlias}/ss")
public List<ServiceSpecificationEntry> queryServiceSpecificationsByAlias(
@PathParam("organizationIdOrAlias") String organizationIdOrAlias
) {
String organizationId = resolveOrganizationIdOrFail(organizationIdOrAlias);
return ApplicationServiceRegistry.serviceSpecificationQueryRepository().findByOwnerId(organizationId);
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("org/{organizationIdOrAlias}/ss/{serviceSpecificationIdOrAlias}")
public ServiceSpecificationEntry getServiceSpecificationByAlias(
@PathParam("organizationIdOrAlias") String organizationIdOrAlias,
@PathParam("serviceSpecificationIdOrAlias") String serviceSpecificationIdOrAlias
) {
String organizationId = resolveOrganizationIdOrFail(organizationIdOrAlias);
return resolveServiceSpecification(organizationId, serviceSpecificationIdOrAlias);
}
// ------------------------------------------------------------------------
// SERVICE INSTANCES
// ------------------------------------------------------------------------
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("org/{organizationIdOrAlias}/si")
public List<ServiceInstanceEntry> queryServiceInstancesByAlias(
@PathParam("organizationIdOrAlias") String organizationIdOrAlias
) {
String organizationId = resolveOrganizationIdOrFail(organizationIdOrAlias);
return ApplicationServiceRegistry.serviceInstanceQueryRepository().findByProviderId(organizationId);
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("org/{organizationIdOrAlias}/si/{serviceInstanceIdOrAlias}")
public ServiceInstanceEntry getServiceInstanceByAlias(
@PathParam("organizationIdOrAlias") String organizationIdOrAlias,
@PathParam("serviceInstanceIdOrAlias") String serviceInstanceIdOrAlias
) {
// TODO: move to almanac api as list aliases ...or something
//System.out.println("ALL: " + ApplicationServiceRegistry.aliasRegistryQueryRepository().findAll());
String organizationId = resolveOrganizationIdOrFail(organizationIdOrAlias);
return resolveServiceInstance(organizationId, serviceInstanceIdOrAlias);
}
private static AliasRegistryEntry lookupAlias(String groupId, Class type, String alias) {
return ApplicationServiceRegistry.aliasRegistryQueryRepository().findByGroupIdAndTypeNameAndAlias(groupId, type.getName(), alias);
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("org/{organizationIdOrAlias}/si/{serviceInstanceIdOrAlias}/alias")
public List<AliasRegistryEntry> queryServiceInstanceAliases(
@PathParam("organizationIdOrAlias") String organizationIdOrAlias,
@PathParam("serviceInstanceIdOrAlias") String serviceInstanceIdOrAlias
) {
return ResourceResolver.queryServiceinstanceAliases(getServiceInstanceByAlias(organizationIdOrAlias, serviceInstanceIdOrAlias));
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("org/{organizationIdOrAlias}/si/{serviceInstanceIdOrAlias}/alias/{alias}")
public AliasRegistryEntry getServiceInstanceAlias(
@PathParam("organizationIdOrAlias") String organizationIdOrAlias,
@PathParam("alias") String alias
) {
String organizationId = resolveOrganizationIdOrFail(organizationIdOrAlias);
return lookupAlias(organizationId, ServiceInstanceId.class, alias);
}
private String overwriteIdentity(String commandJSON, String propertyName, String value) {
return JsonCommandHelper.overwriteIdentity(commandJSON, propertyName, value);
}
}