Skip to content

Commit

Permalink
Merge pull request #31 from francoisledroff/GH-30
Browse files Browse the repository at this point in the history
GH-30 adding a `createOrUpdateProvider()` method to the ProviderService
  • Loading branch information
francoisledroff authored Oct 1, 2021
2 parents 85a2634 + 82fce58 commit dd362e9
Show file tree
Hide file tree
Showing 8 changed files with 373 additions and 12 deletions.
1 change: 1 addition & 0 deletions core/src/main/java/com/adobe/util/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class Constants {
public static final String API_KEY_HEADER = "x-api-key";
public static final String IMS_URL = "https://ims-na1.adobelogin.com";
public static final String API_MANAGEMENT_URL = "https://api.adobe.io";
public static final String CUSTOM_EVENTS_PROVIDER_METADATA_ID = "3rd_party_custom_events";

private Constants() {
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright 2017 Adobe. All rights reserved.
* This file is licensed to you 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 REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package com.adobe.event.management;

import feign.FeignException;
import feign.Response;
import feign.codec.ErrorDecoder;

public class ConflictErrorDecoder implements ErrorDecoder {

@Override
public Exception decode(String methodKey, Response response) {
FeignException exception = FeignException.errorStatus(methodKey, response);
return (response.status()==409) ? new ConflictException(response, exception) : exception;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright 2017 Adobe. All rights reserved.
* This file is licensed to you 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 REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package com.adobe.event.management;

import static com.adobe.util.JacksonUtil.DEFAULT_OBJECT_MAPPER;

import com.adobe.event.management.model.ErrorResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import feign.FeignException;
import feign.Response;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ConflictException extends FeignException {

private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final String conflictingId;

public ConflictException(Response response, FeignException exception) {
super(response.status(), exception.getMessage(), response.request(), exception);
conflictingId = getConflictingId(exception.contentUTF8());
}

public Optional<String> getConflictingId(){
return Optional.ofNullable(conflictingId);
}

private String getConflictingId(String body){
try {
String conflictingId = DEFAULT_OBJECT_MAPPER.readValue(body, ErrorResponse.class).getMessage();
if (!StringUtils.isEmpty(conflictingId) && !conflictingId.contains(" ")) {
return conflictingId;
} else {
logger.warn("The Conflict/409 Error response does not hold a valid conflicting id: `{}`",conflictingId);
return null;
}
} catch (JsonProcessingException e) {
logger.warn("The Conflict/409 Error response is not of the expected format",e.getMessage());
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,30 @@ public interface ProviderService {

Optional<Provider> createProvider(final ProviderInputModel providerCreateModel);

/**
*
* @param providerInputModel the input payload
* @return create and if conflict/409 arises, instead, update a provider using the provided payload
*/
Optional<Provider> createOrUpdateProvider(ProviderInputModel providerInputModel);

Optional<Provider> updateProvider(final String id, final ProviderInputModel providerUpdateModel);

/**
*
* @param instanceId
* @return the `Custom Events` Provider associated with the provided instanceId
*/
Optional<Provider> findCustomEventsProviderByInstanceId(String instanceId);

/**
*
* @param providerMetadataId indicating the type of provider, if you are interested in
* `Custom Events`provider use findCustomEventsProviderByInstanceId
* @param instanceId
* @return the providers list matching the provided criteria and with non-empty event metadata list
* @see #findCustomEventsProviderByInstanceId(String)
*/
Optional<Provider> findProviderBy(final String providerMetadataId, final String instanceId);

List<EventMetadata> getEventMetadata(final String providerId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,20 @@
import com.adobe.event.management.model.Provider;
import com.adobe.event.management.model.ProviderCollection;
import com.adobe.event.management.model.ProviderInputModel;
import com.adobe.util.Constants;
import com.adobe.util.FeignUtil;
import feign.RequestInterceptor;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class ProviderServiceImpl implements ProviderService {

private final Logger logger = LoggerFactory.getLogger(this.getClass());

private final ProviderApi providerApi;
private final EventMetadataApi eventMetadataApi;
private final Workspace workspace;
Expand All @@ -46,6 +51,7 @@ class ProviderServiceImpl implements ProviderService {
workspace.validateWorkspaceContext();
this.providerApi = FeignUtil.getDefaultBuilder()
.requestInterceptor(authInterceptor)
.errorDecoder(new ConflictErrorDecoder())
.target(ProviderApi.class, apiUrl);
this.eventMetadataApi = FeignUtil.getDefaultBuilder()
.requestInterceptor(authInterceptor)
Expand All @@ -71,23 +77,44 @@ public Optional<Provider> findProviderById(final String providerId) {

@Override
public void deleteProvider(final String providerId) {
logger.info("Deleting provider id `{}`",providerId);
providerApi.delete(workspace.getConsumerOrgId(), workspace.getProjectId(),
workspace.getWorkspaceId(), providerId);
}

@Override
public Optional<Provider> createProvider(final ProviderInputModel providerInputModel) {
logger.info("Creating provider using `{}`",providerInputModel);
return providerApi.create(workspace.getConsumerOrgId(), workspace.getProjectId(),
workspace.getWorkspaceId(), providerInputModel);
}

@Override
public Optional<Provider> createOrUpdateProvider(final ProviderInputModel providerInputModel) {
try {
return createProvider(providerInputModel);
}
catch (ConflictException e){
String providerId = e.getConflictingId().orElseThrow(()->e);
logger.info("Another provider (id:`{}`) exist with conflicting natural keys, "
+ "trying to update it ...",providerId);
return updateProvider(providerId,providerInputModel);
}
}

@Override
public Optional<Provider> updateProvider(final String id,
final ProviderInputModel providerUpdateModel) {
logger.info("Updating provider `{}` using `{}`",id, providerUpdateModel);
return providerApi.update(workspace.getConsumerOrgId(), workspace.getProjectId(),
workspace.getWorkspaceId(), id, providerUpdateModel);
}

@Override
public Optional<Provider> findCustomEventsProviderByInstanceId(final String instanceId){
return findProviderBy(Constants.CUSTOM_EVENTS_PROVIDER_METADATA_ID,instanceId);
}

@Override
public Optional<Provider> findProviderBy(final String providerMetadataId,
final String instanceId) {
Expand All @@ -102,7 +129,7 @@ public Optional<Provider> findProviderBy(final String providerMetadataId,
if (providerCollection.get().getProviders().isEmpty()) {
return Optional.empty();
} else {
return Optional.of(providerCollection.get().getProviders().get(1));
return Optional.of(providerCollection.get().getProviders().get(0));
// there can only be one by API contract
}
} else {
Expand All @@ -129,6 +156,7 @@ public Optional<EventMetadata> getEventMetadata(final String providerId, final S
@Override
public Optional<EventMetadata> createEventMetadata(final String providerId,
final EventMetadata eventMetadata) {
logger.info("Creating Event Metadata for provider `{}` using `{}`", providerId, eventMetadata);
return eventMetadataApi.create(
workspace.getConsumerOrgId(), workspace.getProjectId(), workspace.getWorkspaceId(),
providerId, eventMetadata);
Expand All @@ -137,20 +165,23 @@ public Optional<EventMetadata> createEventMetadata(final String providerId,
@Override
public Optional<EventMetadata> updateEventMetadata(final String providerId,
final EventMetadata eventMetadata) {
logger.info("Updating Event Metadata for provider `{}` using `{}`", providerId, eventMetadata);
return eventMetadataApi.update(
workspace.getConsumerOrgId(), workspace.getProjectId(), workspace.getWorkspaceId(),
providerId, eventMetadata.getEventCode(), eventMetadata);
}

@Override
public void deleteEventMetadata(final String providerId, final String eventCode) {
logger.info("Deleting Event Metadata for provider `{}` and eventCode `{}`", providerId, eventCode);
eventMetadataApi.deleteByProviderIdAndEventCode(
workspace.getConsumerOrgId(), workspace.getProjectId(), workspace.getWorkspaceId(),
providerId, eventCode);
}

@Override
public void deleteAllEventMetadata(final String providerId) {
logger.info("Deleting All Event Metadata for provider `{}`", providerId);
eventMetadataApi.deleteByProviderId(
workspace.getConsumerOrgId(), workspace.getProjectId(), workspace.getWorkspaceId(),
providerId);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright 2017 Adobe. All rights reserved.
* This file is licensed to you 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 REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package com.adobe.event.management.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import java.util.Objects;

@JsonInclude(Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class ErrorResponse {

private String reason;
private String message;

public String getReason() {
return reason;
}

public void setReason(String reason) {
this.reason = reason;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ErrorResponse that = (ErrorResponse) o;
return Objects.equals(reason, that.reason) &&
Objects.equals(message, that.message);
}

@Override
public int hashCode() {
return Objects.hash(reason, message);
}

@Override
public String toString() {
return "ErrorResponse{" +
"reason='" + reason + '\'' +
", message='" + message + '\'' +
'}';
}
}
Loading

0 comments on commit dd362e9

Please sign in to comment.