diff options
author | 2017-02-14 15:10:16 +0000 | |
---|---|---|
committer | 2017-08-23 13:18:27 -0400 | |
commit | ac853c1e7186b10e34e392918af31e4ac62b45c2 (patch) | |
tree | 5b0acebf2704317cd9fe86545313e68771bad04f /src/main/java/org/openecomp | |
parent | 19488409d66aa5bbbc2856022f1187ce3f563b83 (diff) |
Make first commit
Transferring from original dcae project
Issue-Id: DCAEGEN2-45
Change-Id: If8500f4a120ec2d27a714c8917f163beb57ee64c
Signed-off-by: Michael Hwang <mhwang@research.att.com>
Diffstat (limited to 'src/main/java/org/openecomp')
28 files changed, 2447 insertions, 0 deletions
diff --git a/src/main/java/org/openecomp/dcae/inventory/InventoryApplication.java b/src/main/java/org/openecomp/dcae/inventory/InventoryApplication.java new file mode 100644 index 0000000..9e78506 --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/InventoryApplication.java @@ -0,0 +1,197 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.dropwizard.cli.Cli; +import io.dropwizard.configuration.ConfigurationFactory; +import io.dropwizard.configuration.ConfigurationFactoryFactory; +import io.dropwizard.configuration.JsonConfigurationFactory; +import io.dropwizard.configuration.UrlConfigurationSourceProvider; +import io.dropwizard.util.JarLocation; +import org.openecomp.dcae.inventory.clients.DCAEControllerClient; +import org.openecomp.dcae.inventory.clients.DatabusControllerClient; +import org.openecomp.dcae.inventory.daos.InventoryDAOManager; +import org.openecomp.dcae.inventory.exceptions.mappers.DBIExceptionMapper; +import org.openecomp.dcae.inventory.exceptions.mappers.DCAEControllerConnectionExceptionMapper; +import org.openecomp.dcae.inventory.exceptions.mappers.DCAEControllerTimeoutExceptionMapper; +import org.openecomp.dcae.inventory.providers.NotFoundExceptionMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import io.dropwizard.Application; +import io.dropwizard.client.JerseyClientBuilder; +import io.dropwizard.setup.Bootstrap; +import io.dropwizard.setup.Environment; +import io.swagger.api.DcaeServiceTypesApi; +import io.swagger.api.DcaeServicesApi; +import io.swagger.api.DcaeServicesGroupbyApi; +import io.swagger.api.factories.DcaeServicesApiServiceFactory; +import io.swagger.jaxrs.config.BeanConfig; +import io.swagger.jaxrs.listing.ApiListingResource; +import io.swagger.jaxrs.listing.SwaggerSerializers; +import io.swagger.models.Contact; +import io.swagger.models.Info; +import org.eclipse.jetty.servlets.CrossOriginFilter; +import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.DispatcherType; +import javax.servlet.FilterRegistration; +import javax.validation.Validator; +import javax.ws.rs.client.Client; +import javax.ws.rs.core.Link; +import java.util.EnumSet; +import java.util.Locale; + + +/** + * Created by mhwang on 4/11/16. + */ +public class InventoryApplication extends Application<InventoryConfiguration> { + + static final Logger LOG = LoggerFactory.getLogger(InventoryApplication.class); + static boolean shouldRemoteFetchConfig = false; + + public static void main(String[] args) throws Exception { + // This is here to try to fix a "high" issue caught by Fortify. Did this **plus** setting locale for each of the + // string comparisons that use `toUpper` because of this StackOverflow post: + // http://stackoverflow.com/questions/38308777/fixed-fortify-scan-locale-changes-are-reappearing + Locale.setDefault(Locale.ENGLISH); + + if (args.length < 2 && "server".equals(args[0])) { + // When the start command is just "server", this will trigger inventory to look for its configuration + // from Consul's KV store. The url is hardcoded here which should be used as the "path" variable into + // the UrlConfigurationSourceProvider. + String[] customArgs = new String[args.length+1]; + System.arraycopy(args, 0, customArgs, 0, args.length); + customArgs[args.length] = "http://consul:8500/v1/kv/inventory?raw=true"; + shouldRemoteFetchConfig = true; + + new InventoryApplication().run(customArgs); + } else { + // You are here because you want to use the default way of configuring inventory - YAML file. + new InventoryApplication().run(args); + } + } + + @Override + public String getName() { + return "dcae-inventory"; + } + + private static class JsonConfigurationFactoryFactory<T> implements ConfigurationFactoryFactory<T> { + @Override + public ConfigurationFactory<T> create(Class<T> klass, Validator validator, ObjectMapper objectMapper, String propertyPrefix) { + return new JsonConfigurationFactory(klass, validator, objectMapper, propertyPrefix); + } + } + + @Override + public void initialize(Bootstrap<InventoryConfiguration> bootstrap) { + // This Info object was lifted from the Swagger generated io.swagger.api.Bootstrap file. Although it was not generated + // correctly. + Info info = new Info().title("DCAE Inventory API").version("0.8.0") + .description("DCAE Inventory is a web service that provides the following:\n\n1. Real-time data on all DCAE services and their components\n2. Comprehensive details on available DCAE service types\n") + .contact(new Contact().email("dcae@lists.openecomp.org")); + // Swagger/servlet/jax-rs magic! + BeanConfig beanConfig = new BeanConfig(); + beanConfig.setInfo(info); + beanConfig.setResourcePackage("io.swagger.api"); + beanConfig.setScan(true); + + if (shouldRemoteFetchConfig) { + // You are here because the configuration is sitting on a remote server in json format + bootstrap.setConfigurationSourceProvider(new UrlConfigurationSourceProvider()); + bootstrap.setConfigurationFactoryFactory(new JsonConfigurationFactoryFactory<>()); + } + } + + @Override + public void run(InventoryConfiguration configuration, Environment environment) { + LOG.info("Starting DCAE inventory application"); + LOG.info(String.format("DB driver properties: %s", configuration.getDataSourceFactory().getProperties().toString())); + InventoryDAOManager.getInstance().setup(environment, configuration); + InventoryDAOManager.getInstance().initialize(); + + // Add filter for CORS support for DCAE dashboard + // http://jitterted.com/tidbits/2014/09/12/cors-for-dropwizard-0-7-x/ + // https://gist.github.com/yunspace/07d80a9ac32901f1e149#file-dropwizardjettycrossoriginintegrationtest-java-L11 + FilterRegistration.Dynamic filter = environment.servlets().addFilter("CORSFilter", CrossOriginFilter.class); + filter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*"); + filter.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*"); + filter.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM, "Content-Type,Authorization,X-Requested-With,Content-Length,Accept,Origin"); + filter.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "GET,PUT,POST,DELETE,OPTIONS"); + filter.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, "*"); + + // Want to serialize Link in a way we like + SimpleModule simpleModule = new SimpleModule(); + simpleModule.addSerializer(Link.class, new LinkSerializer()); + environment.getObjectMapper().registerModule(simpleModule); + + // Setup DCAE controller client + // Used by the dcae-services API + if (configuration.getDcaeControllerConnection().getRequired()) { + final Client clientDCAEController = new JerseyClientBuilder(environment).using(configuration.getJerseyClientConfiguration()) + .build("DCAEControllerClient"); + HttpAuthenticationFeature feature = HttpAuthenticationFeature.basicBuilder().build(); + clientDCAEController.register(feature); + final DCAEControllerClient dcaeControllerClient = new DCAEControllerClient(clientDCAEController, configuration.getDcaeControllerConnection()); + DcaeServicesApiServiceFactory.setDcaeControllerClient(dcaeControllerClient); + + LOG.info("Use of DCAE controller client is required. Turned on."); + } else { + LOG.warn("Use of DCAE controller client is *not* required. Turned off."); + } + + // Setup Databus controller client + // Used by the dcae-services API + if (configuration.getDatabusControllerConnection().getRequired()) { + final Client clientDatabusController = new JerseyClientBuilder(environment).using(configuration.getJerseyClientConfiguration()) + .build("DatabusControllerClient"); + clientDatabusController.register(HttpAuthenticationFeature.basicBuilder().credentials( + configuration.getDatabusControllerConnection().getMechId(), + configuration.getDatabusControllerConnection().getPassword()).build()); + final DatabusControllerClient databusControllerClient = new DatabusControllerClient(clientDatabusController, + configuration.getDatabusControllerConnection()); + DcaeServicesApiServiceFactory.setDatabusControllerClient(databusControllerClient); + + LOG.info("Use of databus controller client is required. Turned on."); + } else { + LOG.warn("Use of databus controller client is *not* required. Turned off."); + } + + environment.jersey().register(NotFoundExceptionMapper.class); + environment.jersey().register(DCAEControllerConnectionExceptionMapper.class); + environment.jersey().register(DCAEControllerTimeoutExceptionMapper.class); + environment.jersey().register(DBIExceptionMapper.UnableToObtainConnectionExceptionMapper.class); + environment.jersey().register(DBIExceptionMapper.UnableToExecuteStatementExceptionMapper.class); + environment.jersey().register(DBIExceptionMapper.UnableToCreateStatementExceptionMapper.class); + + environment.jersey().register(new DcaeServicesApi()); + environment.jersey().register(new DcaeServiceTypesApi()); + environment.jersey().register(new DcaeServicesGroupbyApi()); + + // https://github.com/swagger-api/swagger-core/wiki/Swagger-Core-Jersey-2.X-Project-Setup-1.5 + environment.jersey().register(new ApiListingResource()); + environment.jersey().register(new SwaggerSerializers()); + } + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/InventoryConfiguration.java b/src/main/java/org/openecomp/dcae/inventory/InventoryConfiguration.java new file mode 100644 index 0000000..55bcca2 --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/InventoryConfiguration.java @@ -0,0 +1,173 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.dropwizard.Configuration; +import io.dropwizard.client.JerseyClientConfiguration; +import io.dropwizard.db.DataSourceFactory; +import org.hibernate.validator.constraints.NotEmpty; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +/** + * Created by mhwang on 4/11/16. + */ +public class InventoryConfiguration extends Configuration { + + public static class DCAEControllerConnectionConfiguration { + @NotEmpty + @JsonProperty + private String host; + + @NotNull + @JsonProperty + private Integer port; + + @NotEmpty + @JsonProperty + private String basePath; + + @NotEmpty + @JsonProperty + private String user; + + @NotEmpty + @JsonProperty + private String password; + + @JsonProperty + private Boolean required = true; + + public String getHost() { + return this.host; + } + + public Integer getPort() { + return this.port; + } + + public String getBasePath() { + return this.basePath; + } + + public String getUser() { + return this.user; + } + + public String getPassword() { + return this.password; + } + + public Boolean getRequired() { + return this.required; + } + } + + public static class DatabusControllerConnectionConfiguration { + @NotEmpty + @JsonProperty + private String host; + + @NotNull + @JsonProperty + private Integer port; + + @NotNull + @JsonProperty + private String mechId; + + @NotNull + @JsonProperty + private String password; + + @JsonProperty + private Boolean required = true; + + public String getHost() { + return host; + } + + public Integer getPort() { + return port; + } + + public String getMechId() { + return mechId; + } + + public String getPassword() { + return password; + } + + public Boolean getRequired() { + return this.required; + } + } + + @NotEmpty + private String defaultName = "DCAEInventory"; + + @Valid + @NotNull + @JsonProperty + private DataSourceFactory database = new DataSourceFactory(); + + @NotNull + @JsonProperty + private DCAEControllerConnectionConfiguration dcaeControllerConnection = new DCAEControllerConnectionConfiguration(); + + @NotNull + @JsonProperty + private DatabusControllerConnectionConfiguration databusControllerConnection = new DatabusControllerConnectionConfiguration(); + + @NotNull + @JsonProperty + private JerseyClientConfiguration httpClient = new JerseyClientConfiguration(); + + @JsonProperty + public String getDefaultName() { + return defaultName; + } + + @JsonProperty + public void setDefaultName(String name) { + this.defaultName = name; + } + + public DataSourceFactory getDataSourceFactory() { + return this.database; + } + + public DCAEControllerConnectionConfiguration getDcaeControllerConnection() { + return this.dcaeControllerConnection; + } + + public DatabusControllerConnectionConfiguration getDatabusControllerConnection() { + return databusControllerConnection; + } + + public JerseyClientConfiguration getJerseyClientConfiguration() { + return httpClient; + } + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/LinkSerializer.java b/src/main/java/org/openecomp/dcae/inventory/LinkSerializer.java new file mode 100644 index 0000000..b83697f --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/LinkSerializer.java @@ -0,0 +1,52 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import javax.ws.rs.core.Link; +import java.io.IOException; + +/** + * Lifted from + * http://stackoverflow.com/questions/26989004/how-to-serialize-declarative-links-jersey-with-jackson + * + * Created by mhwang on 5/10/16. + */ +public class LinkSerializer extends JsonSerializer<Link> { + + @Override + public void serialize(Link link, JsonGenerator jg, SerializerProvider sp) throws IOException { + jg.writeStartObject(); + + if (link.getTitle() != null) { + jg.writeStringField("title", link.getTitle()); + } + + jg.writeStringField("rel", link.getRel()); + jg.writeStringField("href", link.getUri().toString()); + jg.writeEndObject(); + } + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/clients/DCAEControllerClient.java b/src/main/java/org/openecomp/dcae/inventory/clients/DCAEControllerClient.java new file mode 100644 index 0000000..adbe8b7 --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/clients/DCAEControllerClient.java @@ -0,0 +1,222 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.clients; + +import org.openecomp.dcae.inventory.InventoryConfiguration; +import org.openecomp.dcae.inventory.exceptions.DCAEControllerClientException; +import org.openecomp.dcae.inventory.exceptions.DCAEControllerConnectionException; +import org.openecomp.dcae.inventory.exceptions.DCAEControllerTimeoutException; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ws.rs.ProcessingException; +import javax.ws.rs.client.Client; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriBuilder; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; + +import static org.glassfish.jersey.client.authentication.HttpAuthenticationFeature.*; + +/** + * Created by mhwang on 5/12/16. + */ +public class DCAEControllerClient { + + /** + * Used for JSON objects of the form: + * "hostService": {"$ref": "/services/vm-docker-host-2/instances/mtl2"} + */ + public static class Reference { + + @JsonProperty("$ref") + private String ref; + + public String getRef() { + return ref; + } + + public void setRef(String ref) { + this.ref = ref; + } + + } + + /** + * Used for the JSON objects returned from /services/{service id}/instances/{instance id} + * calls. + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class ServiceInstance { + + @JsonProperty("status") + private String status; + + /** + * Property points to the Docker host this Docker container runs on. + * This service instance is an application to be run as a Docker container if this value is not null. + */ + @JsonProperty("hostService") + @JsonInclude(JsonInclude.Include.NON_ABSENT) + private Reference hostService; + + /** + * Property points to the CDAP cluster this CDAP application is deployed on. + * This service instance is a CDAP application if this value is not null. + */ + @JsonProperty("clusterService") + @JsonInclude(JsonInclude.Include.NON_ABSENT) + private Reference clusterService; + + /** + * Property points to the location resource that this instance is associated with. + * This property is not null when the service instance is a "pure" VM. + */ + @JsonProperty("location") + @JsonInclude(JsonInclude.Include.NON_ABSENT) + private Reference location; + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public Reference getHostService() { + return hostService; + } + + public void setHostService(Reference hostService) { + this.hostService = hostService; + } + + public Reference getClusterService() { + return clusterService; + } + + public void setClusterService(Reference clusterService) { + this.clusterService = clusterService; + } + + public Reference getLocation() { + return location; + } + + public void setLocation(Reference location) { + this.location = location; + } + + } + + private final static Logger LOG = LoggerFactory.getLogger(DCAEControllerClient.class); + + private final Client client; + private final InventoryConfiguration.DCAEControllerConnectionConfiguration connectionConfiguration; + + public URI constructResourceURI(String resourcePath) { + // TODO: Better way to construct this? + + // Make sure that the resource path has a "/" because the UriBuilder sucks and doesn't do it for us. + if (resourcePath.charAt(0) != '/') { + resourcePath = (new StringBuilder("/")).append(resourcePath).toString(); + } + + StringBuilder actualPath = new StringBuilder("/"); + actualPath.append(this.connectionConfiguration.getBasePath()); + actualPath.append(resourcePath); + + return UriBuilder.fromPath(actualPath.toString()).scheme("http").host(this.connectionConfiguration.getHost()) + .port(this.connectionConfiguration.getPort()).build(); + } + + public ServiceInstance getServiceInstance(String componentId) throws DCAEControllerClientException { + URI uri = constructResourceURI(componentId); + Response response = null; + + try { + response = client.target(uri).request(MediaType.APPLICATION_JSON_TYPE) + .header("Content-Type", "application/json") + .property(HTTP_AUTHENTICATION_BASIC_USERNAME, connectionConfiguration.getUser()) + .property(HTTP_AUTHENTICATION_BASIC_PASSWORD, connectionConfiguration.getPassword()).get(); + } catch (ProcessingException e) { + // Apparently the exceptions are wrapped which is not ideal because many different types of errors are embedded + // in single exception. TODO: May want to come back to split up the errors. + // Example: + // javax.ws.rs.ProcessingException: org.apache.http.conn.ConnectTimeoutException: Connect to <dcae controller domain name>:9998 + String message = "Connecting with DCAE controller probably timed out"; + LOG.error(message, e); + String exceptionMessage = String.format("%s: %s", message, e.getMessage()); + throw new DCAEControllerTimeoutException(exceptionMessage); + } catch (Exception e) { + String message = "Unexpected connection issue with DCAE controller"; + LOG.error(message, e); + String exceptionMessage = String.format("%s: %s", message, e.getMessage()); + throw new DCAEControllerConnectionException(exceptionMessage); + } + + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Received response from DCAE controller: %d", response.getStatus())); + } + + if (response.getStatus() == 200) { + ObjectMapper om = new ObjectMapper(); + + try { + return om.readValue((InputStream) response.getEntity(), ServiceInstance.class); + } catch (IOException e) { + throw new DCAEControllerClientException(e); + } + } + + throw new DCAEControllerClientException(String.format("Unexpected error from DCAE controller: %d", response.getStatus())); + } + + public String getLocation(ServiceInstance serviceInstance) { + if (serviceInstance.getLocation() != null) { + return serviceInstance.getLocation().getRef(); + } else if (serviceInstance.getClusterService() != null) { + // Drill down: Location is on the underlying CDAP cluster service instance + String cdapClusterRef = serviceInstance.getClusterService().getRef(); + return getLocation(getServiceInstance(cdapClusterRef)); + } else if (serviceInstance.getHostService() != null) { + // Drill down: Location is on the underlying Docker host service instance + String dockerHostRef = serviceInstance.getHostService().getRef(); + return getLocation(getServiceInstance(dockerHostRef)); + } else { + throw new DCAEControllerClientException("No valid location for service instance"); + } + } + + public DCAEControllerClient(Client client, + InventoryConfiguration.DCAEControllerConnectionConfiguration connectionConfiguration) { + this.client = client; + this.connectionConfiguration = connectionConfiguration; + } + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/clients/DatabusControllerClient.java b/src/main/java/org/openecomp/dcae/inventory/clients/DatabusControllerClient.java new file mode 100644 index 0000000..9df11d5 --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/clients/DatabusControllerClient.java @@ -0,0 +1,91 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.clients; + +import org.openecomp.dcae.inventory.InventoryConfiguration; +import org.openecomp.dcae.inventory.exceptions.DatabusControllerClientException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import javax.ws.rs.client.Client; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriBuilder; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.util.Map; + +/** + * Created by mhwang on 5/25/16. + */ +public class DatabusControllerClient { + + private final Client client; + private final InventoryConfiguration.DatabusControllerConnectionConfiguration connectionConfiguration; + + public URI constructResourceURI(String resourcePath) { + // Make sure that the resource path has a "/" because the UriBuilder sucks and doesn't do it for us. + if (resourcePath.charAt(0) != '/') { + resourcePath = (new StringBuilder("/")).append(resourcePath).toString(); + } + + return UriBuilder.fromPath(resourcePath.toString()).scheme("https").host(this.connectionConfiguration.getHost()) + .port(this.connectionConfiguration.getPort()).build(); + } + + // TODO: Actually model the JSON objects so that they can be returned to be used for providing useful information + // and thus change this to a "get". + public boolean isExists(String componentId) throws DatabusControllerClientException { + URI uri = constructResourceURI(componentId); + + Response response = client.target(uri).request(MediaType.APPLICATION_JSON_TYPE) + .header("Content-Type", "application/json").get(); + + if (response.getStatus() == 200) { + ObjectMapper om = new ObjectMapper(); + + try { + Map<String, Object> entity = om.readValue((InputStream) response.getEntity(), + new TypeReference<Map<String, Object>>() {}); + + return (entity != null && entity.size() > 0) ? true : false; + } catch (IOException e) { + throw new DatabusControllerClientException(e); + } + } else if (response.getStatus() == 401) { + // You probably got this because your mech id/password is not authorized + throw new DatabusControllerClientException(String.format("Check the mech id/password: %d", response.getStatus())); + } else if (response.getStatus() == 403) { + throw new DatabusControllerClientException(String.format("Credentials not authorized: %d", response.getStatus())); + } + + throw new DatabusControllerClientException(String.format("Unexpected error from databus controller: %d", + response.getStatus())); + } + + public DatabusControllerClient(Client client, + InventoryConfiguration.DatabusControllerConnectionConfiguration connectionConfiguration) { + this.client = client; + this.connectionConfiguration = connectionConfiguration; + } + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/daos/DCAEServiceComponentsDAO.java b/src/main/java/org/openecomp/dcae/inventory/daos/DCAEServiceComponentsDAO.java new file mode 100644 index 0000000..9a674c9 --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/daos/DCAEServiceComponentsDAO.java @@ -0,0 +1,62 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.daos; + +import org.openecomp.dcae.inventory.dbthings.mappers.DCAEServiceComponentObjectMapper; +import org.openecomp.dcae.inventory.dbthings.models.DCAEServiceComponentObject; +import org.skife.jdbi.v2.sqlobject.Bind; +import org.skife.jdbi.v2.sqlobject.BindBean; +import org.skife.jdbi.v2.sqlobject.SqlQuery; +import org.skife.jdbi.v2.sqlobject.SqlUpdate; +import org.skife.jdbi.v2.sqlobject.customizers.Mapper; + +import java.util.List; + +/** + * Created by mhwang on 4/19/16. + */ +public interface DCAEServiceComponentsDAO extends InventoryDAO { + + @SqlQuery("select exists (select * from information_schema.tables where table_name = \'dcae_service_components\')") + Boolean checkIfTableExists(); + + @SqlUpdate("create table dcae_service_components (component_id varchar not null primary key, component_type varchar not null, " + + "component_source varchar not null, shareable integer default 0, created timestamp not null, modified timestamp not null)") + void createTable(); + + @SqlUpdate("insert into dcae_service_components (component_id, component_type, component_source, shareable, created, modified) " + + "values (:componentId, :componentType, :componentSource, :shareable, :created, :modified)") + void insert(@BindBean DCAEServiceComponentObject componentObject); + + @SqlUpdate("update dcae_service_components set component_type = :componentType, component_source = :componentSource, " + + "shareable = :shareable, modified = :modified where component_id = :componentId") + void update(@BindBean DCAEServiceComponentObject componentObject); + + @Mapper(DCAEServiceComponentObjectMapper.class) + @SqlQuery("select c.* from dcae_services_components_maps m join dcae_service_components c " + + "on m.component_id = c.component_id where m.service_id = :it") + List<DCAEServiceComponentObject> getByServiceId(@Bind String serviceId); + + @Mapper(DCAEServiceComponentObjectMapper.class) + @SqlQuery("select c.* from dcae_service_components c where c.component_id = :it") + DCAEServiceComponentObject getByComponentId(@Bind String componentId); + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/daos/DCAEServiceTransactionDAO.java b/src/main/java/org/openecomp/dcae/inventory/daos/DCAEServiceTransactionDAO.java new file mode 100644 index 0000000..f0fca86 --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/daos/DCAEServiceTransactionDAO.java @@ -0,0 +1,158 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.daos; + +import org.openecomp.dcae.inventory.dbthings.models.DCAEServiceComponentObject; +import org.openecomp.dcae.inventory.dbthings.models.DCAEServiceObject; +import org.joda.time.DateTime; +import org.skife.jdbi.v2.sqlobject.CreateSqlObject; +import org.skife.jdbi.v2.sqlobject.Transaction; + +import java.util.ArrayList; +import java.util.List; + +/** + * This is based-off of this blog post. + * http://manikandan-k.github.io/2015/05/10/Transactions_in_jdbi.html + * + * Created by mhwang on 4/21/16. + */ +public abstract class DCAEServiceTransactionDAO { + + public static class DCAEServiceTransactionContext { + + private final String serviceId; + private final DateTime modified; + private DCAEServiceObject serviceObjectToInsert; + private DCAEServiceObject serviceObjectToUpdate; + private List<DCAEServiceComponentObject> componentObjectsToInsert; + private List<DCAEServiceComponentObject> componentObjectsToUpdate; + private List<String> mappingsToInsert; + private List<String> mappingsToDelete; + + public String getServiceId() { + return serviceId; + } + + public DateTime getModified() { + return modified; + } + + public DCAEServiceObject getServiceObjectToInsert() { + return serviceObjectToInsert; + } + + public void setServiceObjectToInsert(DCAEServiceObject serviceObjectToInsert) { + this.serviceObjectToInsert = serviceObjectToInsert; + } + + public DCAEServiceObject getServiceObjectToUpdate() { + return serviceObjectToUpdate; + } + + public void setServiceObjectToUpdate(DCAEServiceObject serviceObjectToUpdate) { + this.serviceObjectToUpdate = serviceObjectToUpdate; + } + + public List<DCAEServiceComponentObject> getComponentObjectsToInsert() { + return componentObjectsToInsert; + } + + public List<DCAEServiceComponentObject> addComponentObjectToInsert(DCAEServiceComponentObject componentObject) { + this.componentObjectsToInsert.add(componentObject); + return this.componentObjectsToInsert; + } + + public List<DCAEServiceComponentObject> getComponentObjectsToUpdate() { + return componentObjectsToUpdate; + } + + public List<DCAEServiceComponentObject> addComponentObjectToUpdate(DCAEServiceComponentObject componentObject) { + this.componentObjectsToUpdate.add(componentObject); + return this.componentObjectsToUpdate; + } + + public List<String> getMappingsToInsert() { + return mappingsToInsert; + } + + public List<String> addMappingsToInsert(String componentId) { + this.mappingsToInsert.add(componentId); + return this.mappingsToInsert; + } + + public List<String> getMappingsToDelete() { + return mappingsToDelete; + } + + public List<String> addMappingsToDelete(String componentId) { + this.mappingsToDelete.add(componentId); + return this.mappingsToDelete; + } + + public DCAEServiceTransactionContext(String serviceId, DateTime modified) { + this.serviceId = serviceId; + this.modified = modified; + this.componentObjectsToInsert = new ArrayList<>(); + this.componentObjectsToUpdate = new ArrayList<>(); + this.mappingsToInsert = new ArrayList<>(); + this.mappingsToDelete = new ArrayList<>(); + } + + } + + @CreateSqlObject + abstract DCAEServicesDAO getServicesDAO(); + + @CreateSqlObject + abstract DCAEServicesComponentsMapsDAO getServicesComponentsMappingDAO(); + + @CreateSqlObject + abstract DCAEServiceComponentsDAO getComponentsDAO(); + + @Transaction + public void insert(DCAEServiceTransactionContext context) { + if (context.getServiceObjectToInsert() != null) { + this.getServicesDAO().insert(context.getServiceObjectToInsert()); + } + + if (context.getServiceObjectToUpdate() != null) { + this.getServicesDAO().update(context.getServiceObjectToUpdate()); + } + + for (DCAEServiceComponentObject sco : context.getComponentObjectsToInsert()) { + this.getComponentsDAO().insert(sco); + } + + for (DCAEServiceComponentObject sco : context.getComponentObjectsToUpdate()) { + this.getComponentsDAO().update(sco); + } + + for (String componentId : context.getMappingsToInsert()) { + this.getServicesComponentsMappingDAO().insert(context.getServiceId(), componentId, context.getModified()); + } + + for (String componentId : context.getMappingsToDelete()) { + this.getServicesComponentsMappingDAO().delete(context.serviceId, componentId); + } + } + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/daos/DCAEServiceTypesDAO.java b/src/main/java/org/openecomp/dcae/inventory/daos/DCAEServiceTypesDAO.java new file mode 100644 index 0000000..50b79b2 --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/daos/DCAEServiceTypesDAO.java @@ -0,0 +1,90 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.daos; + +import org.openecomp.dcae.inventory.dbthings.mappers.DCAEServiceTypeObjectMapper; + +import org.openecomp.dcae.inventory.dbthings.models.DCAEServiceTypeObject; +import io.swagger.model.DCAEServiceTypeRequest; +import org.skife.jdbi.v2.sqlobject.Bind; +import org.skife.jdbi.v2.sqlobject.BindBean; +import org.skife.jdbi.v2.sqlobject.SqlQuery; +import org.skife.jdbi.v2.sqlobject.SqlUpdate; +import org.skife.jdbi.v2.sqlobject.customizers.Mapper; + +/** + * DCAE service type records are no longer treated immutable because versioning is handled by clients + * to DCAE inventory i.e. ASDC. There is field "deactivated" that determines if a service type is active. + * Inserts and updates automatically activates a service type while deleting deactivates a service type. + * + * Created by mhwang on 4/19/16. + */ +public interface DCAEServiceTypesDAO extends InventoryDAO { + + @SqlQuery("select exists (select * from information_schema.tables where table_name = \'dcae_service_types\')") + Boolean checkIfTableExists(); + + /** + * Note that service_ids and service_locations are nullable fields. This might not be the right decision but because + * the resource model allows for nulls, thought it should consistent. + */ + @SqlUpdate("create table dcae_service_types (type_id varchar not null, type_version integer not null, " + + "type_name varchar not null, owner varchar not null, blueprint_template text not null, " + + "vnf_types varchar[] not null, service_ids varchar[], service_locations varchar[], " + + "asdc_service_id varchar, asdc_resource_id varchar, " + + "created timestamp not null, deactivated timestamp, constraint pk_type_created primary key (type_id))") + void createTable(); + + // REVIEW: asdcServiceId and asdcResourceId is implicitly part of the unique key and thus shouldn't be updated. + @SqlUpdate("insert into dcae_service_types(type_id, type_version, type_name, owner, blueprint_template, vnf_types, " + + "service_ids, service_locations, asdc_service_id, asdc_resource_id, created, deactivated) " + + "values (:typeId, :typeVersion, :typeName, :owner, :blueprintTemplate, :vnfTypes, :serviceIds, " + + ":serviceLocations, :asdcServiceId, :asdcResourceId, :created, null)") + void insert(@BindBean DCAEServiceTypeObject serviceObject); + + @SqlUpdate("update dcae_service_types set " + + "owner = :owner, blueprint_template = :blueprintTemplate, vnf_types = :vnfTypes, " + + "service_ids = :serviceIds, service_locations = :serviceLocations, created = :created, " + + "deactivated = null where type_id = :typeId") + void update(@BindBean DCAEServiceTypeObject serviceObject); + + @SqlUpdate("update dcae_service_types set deactivated = (now() at time zone 'utc') where type_id = :typeId") + void deactivateExisting(@Bind("typeId") String typeId); + + @Mapper(DCAEServiceTypeObjectMapper.class) + @SqlQuery("select * from dcae_service_types where type_id = :it") + DCAEServiceTypeObject getByTypeId(@Bind String typeId); + + @Mapper(DCAEServiceTypeObjectMapper.class) + @SqlQuery("select * from dcae_service_types where deactivated is null and type_id = :it") + DCAEServiceTypeObject getByTypeIdActiveOnly(@Bind String typeId); + + @Mapper(DCAEServiceTypeObjectMapper.class) + @SqlQuery("select * from dcae_service_types where type_name = :typeName and type_version = :typeVersion " + + "and asdc_service_id is null and asdc_resource_id is null") + DCAEServiceTypeObject getByRequestFromNotASDC(@BindBean DCAEServiceTypeRequest serviceTypeObject); + + @Mapper(DCAEServiceTypeObjectMapper.class) + @SqlQuery("select * from dcae_service_types where type_name = :typeName and type_version = :typeVersion " + + "and asdc_service_id = :asdcServiceId and asdc_resource_id = :asdcResourceId") + DCAEServiceTypeObject getByRequestFromASDC(@BindBean DCAEServiceTypeRequest serviceTypeObject); + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/daos/DCAEServicesComponentsMapsDAO.java b/src/main/java/org/openecomp/dcae/inventory/daos/DCAEServicesComponentsMapsDAO.java new file mode 100644 index 0000000..5bfd3cd --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/daos/DCAEServicesComponentsMapsDAO.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.daos; + +import org.joda.time.DateTime; +import org.skife.jdbi.v2.sqlobject.Bind; +import org.skife.jdbi.v2.sqlobject.SqlQuery; +import org.skife.jdbi.v2.sqlobject.SqlUpdate; + +/** + * This class manages the joining table called "dcae_services_components_maps" which maps the many-to-many relationship + * between DCAE services and DCAE service components. + * + * Created by mhwang on 4/19/16. + */ +public interface DCAEServicesComponentsMapsDAO extends InventoryDAO { + + @SqlQuery("select exists (select * from information_schema.tables where table_name = \'dcae_services_components_maps\')") + Boolean checkIfTableExists(); + + @SqlUpdate("create table dcae_services_components_maps (service_id varchar not null references dcae_services (service_id), " + + "component_id varchar not null references dcae_service_components (component_id), " + + "created timestamp not null, primary key (service_id, component_id))") + void createTable(); + + @SqlUpdate("insert into dcae_services_components_maps (service_id, component_id, created) values (:serviceId, :componentId, :created)") + void insert(@Bind("serviceId") String serviceId, @Bind("componentId") String componentId, @Bind("created") DateTime created); + + @SqlUpdate("delete from dcae_services_components_maps where service_id = :serviceId and component_id = :componentId") + void delete(@Bind("serviceId") String serviceId, @Bind("componentId") String componentId); + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/daos/DCAEServicesDAO.java b/src/main/java/org/openecomp/dcae/inventory/daos/DCAEServicesDAO.java new file mode 100644 index 0000000..9200677 --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/daos/DCAEServicesDAO.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.daos; + +import org.openecomp.dcae.inventory.dbthings.mappers.DCAEServiceObjectMapper; +import org.openecomp.dcae.inventory.dbthings.models.DCAEServiceObject; +import org.joda.time.DateTime; +import org.skife.jdbi.v2.sqlobject.Bind; +import org.skife.jdbi.v2.sqlobject.BindBean; +import org.skife.jdbi.v2.sqlobject.SqlQuery; +import org.skife.jdbi.v2.sqlobject.SqlUpdate; +import org.skife.jdbi.v2.sqlobject.customizers.Mapper; +import org.skife.jdbi.v2.util.IntegerMapper; + + +/** + * Created by mhwang on 4/19/16. + */ +public interface DCAEServicesDAO extends InventoryDAO { + + @SqlQuery("select exists (select * from information_schema.tables where table_name = \'dcae_services\')") + Boolean checkIfTableExists(); + + @SqlUpdate("create table dcae_services (service_id varchar not null primary key, type_id varchar not null, " + + "vnf_id varchar not null, vnf_type varchar not null, vnf_location varchar not null, deployment_ref varchar, " + + "created timestamp not null, modified timestamp not null, status varchar not null)") + void createTable(); + + @SqlUpdate("insert into dcae_services(service_id, type_id, vnf_id, vnf_type, vnf_location, deployment_ref, " + + "created, modified, status) values (:serviceId, :typeId, :vnfId, :vnfType, :vnfLocation, :deploymentRef, " + + ":created, :modified, :status)") + void insert(@BindBean DCAEServiceObject serviceObject); + + @SqlUpdate("update dcae_services set type_id = :typeId, vnf_id = :vnfId, vnf_type = :vnfType, " + + "vnf_location = :vnfLocation, deployment_ref = :deploymentRef, modified = :modified, status = :status " + + "where service_id = :serviceId") + void update(@BindBean DCAEServiceObject serviceObject); + + @Mapper(DCAEServiceObjectMapper.class) + @SqlQuery("select * from dcae_services where status = :status and service_id = :serviceId") + DCAEServiceObject getByServiceId(@Bind("status") DCAEServiceObject.DCAEServiceStatus status, @Bind("serviceId") String serviceId); + + @Mapper(DCAEServiceObjectMapper.class) + @SqlQuery("select * from dcae_services where service_id = :serviceId") + DCAEServiceObject getByServiceId(@Bind("serviceId") String serviceId); + + @SqlUpdate("update dcae_services set modified = :modified, status = :status where service_id = :serviceId") + void updateStatusByServiceId(@Bind("modified") DateTime modified, + @Bind("status") DCAEServiceObject.DCAEServiceStatus status, + @Bind("serviceId") String serviceId); + + @Mapper(IntegerMapper.class) + @SqlQuery("select count(1) from dcae_services where status = :status and type_id = :typeId") + Integer countByType(@Bind("status") DCAEServiceObject.DCAEServiceStatus status, @Bind("typeId") String typeId); + +} + + diff --git a/src/main/java/org/openecomp/dcae/inventory/daos/InventoryDAO.java b/src/main/java/org/openecomp/dcae/inventory/daos/InventoryDAO.java new file mode 100644 index 0000000..ef2fb8d --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/daos/InventoryDAO.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.daos; + +/** + * Created by mhwang on 4/19/16. + */ +public interface InventoryDAO { + Boolean checkIfTableExists(); + void createTable(); +} diff --git a/src/main/java/org/openecomp/dcae/inventory/daos/InventoryDAOManager.java b/src/main/java/org/openecomp/dcae/inventory/daos/InventoryDAOManager.java new file mode 100644 index 0000000..77611b5 --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/daos/InventoryDAOManager.java @@ -0,0 +1,181 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.daos; + +import org.openecomp.dcae.inventory.InventoryConfiguration; +import org.openecomp.dcae.inventory.dbthings.StringListArgument; +import io.dropwizard.jdbi.DBIFactory; +import io.dropwizard.setup.Environment; +import org.skife.jdbi.v2.DBI; +import org.skife.jdbi.v2.Handle; +import org.skife.jdbi.v2.util.BooleanMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; +import java.util.List; + +/** + * Reluctantly made this into a singleton in order to have access to the DAOs in the request handling code. Didn't + * want to change the interface on the handlers because they are generated by Swagger and I wanted to flexibility + * to swap in changes easily. This meant sacrificing dependency injection which is preferred. + * + * Created by mhwang on 4/19/16. + */ +public final class InventoryDAOManager { + + private static InventoryDAOManager instance; + + public static InventoryDAOManager getInstance() { + if (instance == null) { + instance = new InventoryDAOManager(); + } + + return instance; + } + + public static class InventoryDAOManagerSetupException extends RuntimeException { + + public InventoryDAOManagerSetupException(String message) { + super(message); + } + + } + + private final static Logger LOG = LoggerFactory.getLogger(InventoryDAOManager.class); + // WATCH! Table creation order matters where mapping tables refer to other tables for foreign keys. + private final static List<Class> DAO_CLASSES = Arrays.asList(DCAEServiceTypesDAO.class, DCAEServicesDAO.class, + DCAEServiceComponentsDAO.class, DCAEServicesComponentsMapsDAO.class); + + private DBI jdbi; + private Environment environment; + private InventoryConfiguration configuration; + + private InventoryDAOManager() { + } + + /** + * Setup the manager + * + * Saving the Dropwizard environment and configuration which are used to construct the DBI object in a later + * initialize call. This method can only be called once to be safe and to avoid runtime problems that could be + * caused if the global instance of this class gets into a weird state (Couldn't use Java's `final` qualifier). + * + * @param environment + * @param inventoryConfiguration + */ + public void setup(Environment environment, InventoryConfiguration inventoryConfiguration) { + if (this.environment == null && this.configuration == null) { + this.environment = environment; + this.configuration = inventoryConfiguration; + } else { + throw new InventoryDAOManagerSetupException("InventoryDAOManager setup can only be called once."); + } + } + + /** + * Initialize the manager + * + * Create the underlying validated DBI object that is used to manage database connections + */ + public void initialize() { + final DBIFactory factory = new DBIFactory(); + final DBI jdbi = factory.build(this.environment, this.configuration.getDataSourceFactory(), "dcae-database"); + jdbi.registerArgumentFactory(new StringListArgument()); + + for (Class<? extends InventoryDAO> daoClass : DAO_CLASSES) { + final InventoryDAO dao = jdbi.onDemand(daoClass); + + if (dao.checkIfTableExists()) { + LOG.info(String.format("Sql table exists: %s", daoClass.getSimpleName())); + } else { + dao.createTable(); + LOG.info(String.format("Sql table created: %s", daoClass.getSimpleName())); + } + } + + // CREATE VIEWS + // TODO: This doesn't belong here and is not consistent with the above approach. Make it better. + try (Handle jdbiHandle = jdbi.open()) { + String viewName = "dcae_service_types_latest"; + String checkQuery = String.format("select exists (select * from information_schema.tables where table_name = '%s')", + viewName); + + if (jdbiHandle.createQuery(checkQuery).map(BooleanMapper.FIRST).first()) { + LOG.info(String.format("Sql view exists: %s", viewName)); + } else { + StringBuilder sb = new StringBuilder(String.format("create view %s as ", viewName)); + sb.append("select s.* from dcae_service_types s "); + sb.append("join (select type_name, max(type_version) as max_version from dcae_service_types group by type_name) as f "); + sb.append("on s.type_name = f.type_name and s.type_version = f.max_version"); + + jdbiHandle.execute(sb.toString()); + LOG.info(String.format("Sql view created: %s", viewName)); + } + } catch (Exception e) { + throw new RuntimeException("", e); + } + + // Do this assignment at the end after performing table checks to ensure that connection is good + this.jdbi = jdbi; + } + + private InventoryDAO getDAO(Class<? extends InventoryDAO> klass) { + if (jdbi == null) { + throw new RuntimeException("InventoryDAOManager has not been initialized!"); + } + + // Using this approach to constructing the DAO, the client is not responsible for closing the handle. + // http://jdbi.org/sql_object_overview/ + // > In this case we do not need to (and in fact shouldn’t) ever take action to close the handle the sql object uses. + return jdbi.onDemand(klass); + } + + public DCAEServicesDAO getDCAEServicesDAO() { + return (DCAEServicesDAO) this.getDAO(DCAEServicesDAO.class); + } + + public DCAEServiceComponentsDAO getDCAEServiceComponentsDAO() { + return (DCAEServiceComponentsDAO) this.getDAO(DCAEServiceComponentsDAO.class); + } + + public DCAEServicesComponentsMapsDAO getDCAEServicesComponentsDAO() { + return (DCAEServicesComponentsMapsDAO) this.getDAO(DCAEServicesComponentsMapsDAO.class); + } + + public DCAEServiceTransactionDAO getDCAEServiceTransactionDAO() { + return jdbi.onDemand(DCAEServiceTransactionDAO.class); + } + + public DCAEServiceTypesDAO getDCAEServiceTypesDAO() { + return (DCAEServiceTypesDAO) this.getDAO(DCAEServiceTypesDAO.class); + } + + /** + * Must close the handle that is returned here. It is AutoCloseable so just use it as a try-with-resource. + * + * @return + */ + public Handle getHandle() { + return this.jdbi.open(); + } + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/dbthings/StringListArgument.java b/src/main/java/org/openecomp/dcae/inventory/dbthings/StringListArgument.java new file mode 100644 index 0000000..afd0e78 --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/dbthings/StringListArgument.java @@ -0,0 +1,57 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.dbthings; + +import org.skife.jdbi.v2.StatementContext; +import org.skife.jdbi.v2.tweak.Argument; +import org.skife.jdbi.v2.tweak.ArgumentFactory; + +import java.sql.Array; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.List; + +/** + * This class if needed for jdbi queries to be able to properly bind List<String> objects. + * + * http://stackoverflow.com/questions/33062516/insert-2d-array-into-postresql-db-using-jdbi + * + * Created by mhwang on 5/4/16. + */ +public class StringListArgument implements ArgumentFactory<List<String>> { + + @Override + public boolean accepts(Class<?> expectedType, Object value, StatementContext statementContext) { + return value != null && List.class.isAssignableFrom(value.getClass()); + } + + @Override + public Argument build(Class<?> expectedType, List<String> value, StatementContext statementContext) { + return new Argument() { + @Override + public void apply(int position, PreparedStatement statement, StatementContext ctx) throws SQLException { + Array values = statement.getConnection().createArrayOf("varchar", value.toArray()); + statement.setArray(position, values); + } + }; + } + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/dbthings/mappers/DCAEServiceComponentObjectMapper.java b/src/main/java/org/openecomp/dcae/inventory/dbthings/mappers/DCAEServiceComponentObjectMapper.java new file mode 100644 index 0000000..23b42b1 --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/dbthings/mappers/DCAEServiceComponentObjectMapper.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.dbthings.mappers; + +import org.openecomp.dcae.inventory.dbthings.models.DCAEServiceComponentObject; +import org.joda.time.DateTime; +import org.skife.jdbi.v2.StatementContext; +import org.skife.jdbi.v2.tweak.ResultSetMapper; + +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * Created by mhwang on 4/19/16. + */ +public class DCAEServiceComponentObjectMapper implements ResultSetMapper<DCAEServiceComponentObject> { + + @Override + public DCAEServiceComponentObject map(int i, ResultSet resultSet, StatementContext statementContext) throws SQLException { + DCAEServiceComponentObject object = new DCAEServiceComponentObject(); + object.setComponentId(resultSet.getString("component_id")); + object.setComponentType(resultSet.getString("component_type")); + object.setComponentSource(resultSet.getString("component_source")); + object.setShareable(resultSet.getInt("shareable")); + object.setCreated(new DateTime(resultSet.getTimestamp("created"))); + object.setModified(new DateTime(resultSet.getTimestamp("modified"))); + return object; + } + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/dbthings/mappers/DCAEServiceObjectMapper.java b/src/main/java/org/openecomp/dcae/inventory/dbthings/mappers/DCAEServiceObjectMapper.java new file mode 100644 index 0000000..27cb22f --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/dbthings/mappers/DCAEServiceObjectMapper.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.dbthings.mappers; + +import org.openecomp.dcae.inventory.dbthings.models.DCAEServiceObject; +import org.joda.time.DateTime; +import org.skife.jdbi.v2.StatementContext; +import org.skife.jdbi.v2.tweak.ResultSetMapper; + +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * Created by mhwang on 4/19/16. + */ +public class DCAEServiceObjectMapper implements ResultSetMapper<DCAEServiceObject> { + + @Override + public DCAEServiceObject map(int i, ResultSet resultSet, StatementContext statementContext) throws SQLException { + DCAEServiceObject object = new DCAEServiceObject(); + object.setServiceId(resultSet.getString("service_id")); + object.setTypeId(resultSet.getString("type_id")); + object.setVnfId(resultSet.getString("vnf_id")); + object.setVnfType(resultSet.getString("vnf_type")); + object.setVnfLocation(resultSet.getString("vnf_location")); + object.setDeploymentRef(resultSet.getString("deployment_ref")); + object.setCreated(new DateTime(resultSet.getTimestamp("created"))); + object.setModified(new DateTime(resultSet.getTimestamp("modified"))); + object.setStatus(DCAEServiceObject.DCAEServiceStatus.valueOf(resultSet.getString("status"))); + return object; + } + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/dbthings/mappers/DCAEServiceTypeObjectMapper.java b/src/main/java/org/openecomp/dcae/inventory/dbthings/mappers/DCAEServiceTypeObjectMapper.java new file mode 100644 index 0000000..dc64423 --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/dbthings/mappers/DCAEServiceTypeObjectMapper.java @@ -0,0 +1,73 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.dbthings.mappers; + +import org.openecomp.dcae.inventory.dbthings.models.DCAEServiceTypeObject; +import org.joda.time.DateTime; +import org.skife.jdbi.v2.StatementContext; +import org.skife.jdbi.v2.tweak.ResultSetMapper; + +import java.sql.Array; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.Arrays; + +/** + * Created by mhwang on 5/3/16. + */ +public class DCAEServiceTypeObjectMapper implements ResultSetMapper<DCAEServiceTypeObject> { + + @Override + public DCAEServiceTypeObject map(int i, ResultSet resultSet, StatementContext statementContext) throws SQLException { + DCAEServiceTypeObject object = new DCAEServiceTypeObject(); + object.setTypeId(resultSet.getString("type_id")); + object.setTypeName(resultSet.getString("type_name")); + object.setTypeVersion(resultSet.getInt("type_version")); + object.setOwner(resultSet.getString("owner")); + String[] vnfTypes = (String[]) resultSet.getArray("vnf_types").getArray(); + object.setVnfTypes(Arrays.asList(vnfTypes)); + + Array serviceIdsArray = resultSet.getArray("service_ids"); + + if (serviceIdsArray != null) { + String[] serviceIds = (String[]) serviceIdsArray.getArray(); + object.setServiceIds(Arrays.asList(serviceIds)); + } + + Array serviceLocationsArray = resultSet.getArray("service_locations"); + + if (serviceLocationsArray != null) { + String[] serviceLocations = (String[]) serviceLocationsArray.getArray(); + object.setServiceLocations(Arrays.asList(serviceLocations)); + } + + object.setBlueprintTemplate(resultSet.getString("blueprint_template")); + object.setAsdcServiceId(resultSet.getString("asdc_service_id")); + object.setAsdcResourceId(resultSet.getString("asdc_resource_id")); + object.setCreated(new DateTime(resultSet.getTimestamp("created"))); + + Timestamp deactivated = resultSet.getTimestamp("deactivated"); + object.setDeactivated(deactivated == null ? null : new DateTime(deactivated)); + return object; + } + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/dbthings/models/DCAEServiceComponentObject.java b/src/main/java/org/openecomp/dcae/inventory/dbthings/models/DCAEServiceComponentObject.java new file mode 100644 index 0000000..0ec9c19 --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/dbthings/models/DCAEServiceComponentObject.java @@ -0,0 +1,146 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.dbthings.models; + +import io.swagger.model.DCAEServiceComponentRequest; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; + +/** + * Created by mhwang on 4/19/16. + */ +public class DCAEServiceComponentObject { + + private String componentId = null; + private DateTime created = null; + private DateTime modified = null; + private String componentType = null; + private String componentSource = null; + private Integer shareable = null; + + public String getComponentId() { + return componentId; + } + + public void setComponentId(String componentId) { + this.componentId = componentId; + } + + public DateTime getCreated() { + return created; + } + + public void setCreated(DateTime created) { + this.created = created; + } + + public DateTime getModified() { + return modified; + } + + public void setModified(DateTime modified) { + this.modified = modified; + } + + public String getComponentType() { + return componentType; + } + + public void setComponentType(String componentType) { + this.componentType = componentType; + } + + public String getComponentSource() { + return componentSource; + } + + public void setComponentSource(String componentSource) { + this.componentSource = componentSource; + } + + public Integer getShareable() { + return shareable; + } + + public void setShareable(Integer shareable) { + this.shareable = shareable; + } + + public DCAEServiceComponentObject() { + } + + /** + * Intended to be used for inserts - new objects. + * + * @param request + */ + public DCAEServiceComponentObject(DCAEServiceComponentRequest request) { + DateTime now = DateTime.now(DateTimeZone.UTC); + this.setComponentId(request.getComponentId()); + this.setComponentType(request.getComponentType()); + this.setComponentSource(request.getComponentSource()); + this.setCreated(now); + this.setModified(now); + this.setShareable(request.getShareable()); + } + + /** + * Intended to be used for updates - some fields should not be updated. + * + * @param source + * @param updateRequest + */ + public DCAEServiceComponentObject(DCAEServiceComponentObject source, DCAEServiceComponentRequest updateRequest) { + // Immutable fields + this.setComponentId(source.getComponentId()); + this.setCreated(source.getCreated()); + + // Mutable fields + this.setComponentType(updateRequest.getComponentType()); + this.setComponentSource(updateRequest.getComponentSource()); + this.setShareable(updateRequest.getShareable()); + this.setModified(DateTime.now(DateTimeZone.UTC)); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class DCAEServiceComponentObject {\n"); + + sb.append(" componentId: ").append(toIndentedString(componentId)).append("\n"); + sb.append(" componentType: ").append(toIndentedString(componentType)).append("\n"); + sb.append(" componentSource: ").append(toIndentedString(componentSource)).append("\n"); + sb.append(" shareable: ").append(toIndentedString(shareable)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} diff --git a/src/main/java/org/openecomp/dcae/inventory/dbthings/models/DCAEServiceObject.java b/src/main/java/org/openecomp/dcae/inventory/dbthings/models/DCAEServiceObject.java new file mode 100644 index 0000000..4374acd --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/dbthings/models/DCAEServiceObject.java @@ -0,0 +1,168 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.dbthings.models; + +import io.swagger.model.DCAEServiceRequest; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; + +/** + * Created by mhwang on 4/19/16. + */ +public class DCAEServiceObject { + + public static enum DCAEServiceStatus { + RUNNING, + REMOVED + } + + private String serviceId = null; + private String typeId = null; + private DateTime created = null; + private DateTime modified = null; + private String vnfId = null; + private String vnfType = null; + private String vnfLocation = null; + private String deploymentRef = null; + + // These properties are meant to be used internally in the service only + private DCAEServiceStatus status = null; + + public String getServiceId() { + return serviceId; + } + + public void setServiceId(String serviceId) { + this.serviceId = serviceId; + } + + public String getTypeId() { + return typeId; + } + + public void setTypeId(String typeId) { + this.typeId = typeId; + } + + public DateTime getCreated() { + return created; + } + + public void setCreated(DateTime created) { + this.created = created; + } + + public DateTime getModified() { + return modified; + } + + public void setModified(DateTime modified) { + this.modified = modified; + } + + public DCAEServiceStatus getStatus() { + return status; + } + + public void setStatus(DCAEServiceStatus status) { + this.status = status; + } + + public String getVnfId() { + return vnfId; + } + + public void setVnfId(String vnfId) { + this.vnfId = vnfId; + } + + public String getVnfType() { + return vnfType; + } + + public void setVnfType(String vnfType) { + this.vnfType = vnfType; + } + + public String getVnfLocation() { + return vnfLocation; + } + + public void setVnfLocation(String vnfLocation) { + this.vnfLocation = vnfLocation; + } + + public String getDeploymentRef() { + return deploymentRef; + } + + public void setDeploymentRef(String deploymentRef) { + this.deploymentRef = deploymentRef; + } + + public DCAEServiceObject() { + } + + // TODO: Move the constructors functionality below out into the actual handlers. + + /** + * Intended to be used for inserts - new objects. + * + * @param serviceId + * @param request + */ + public DCAEServiceObject(String serviceId, DCAEServiceRequest request) { + DateTime now = DateTime.now(DateTimeZone.UTC); + this.setServiceId(serviceId); + this.setTypeId(request.getTypeId()); + this.setVnfId(request.getVnfId()); + this.setVnfType(request.getVnfType()); + this.setVnfLocation(request.getVnfLocation()); + this.setDeploymentRef(request.getDeploymentRef()); + this.setCreated(now); + this.setModified(now); + // Assumption here is that you are here from the PUT which means that the service is RUNNING. + this.setStatus(DCAEServiceStatus.RUNNING); + } + + /** + * Intended to be used for updates - some fields should not be updated. + * + * @param source + * @param updateRequest + */ + public DCAEServiceObject(DCAEServiceObject source, DCAEServiceRequest updateRequest) { + // Immutable fields + this.setServiceId(source.getServiceId()); + this.setCreated(source.getCreated()); + + // Mutable fields + this.setTypeId(updateRequest.getTypeId()); + this.setVnfId(updateRequest.getVnfId()); + this.setVnfType(updateRequest.getVnfType()); + this.setVnfLocation(updateRequest.getVnfLocation()); + this.setDeploymentRef(updateRequest.getDeploymentRef()); + this.setModified(DateTime.now(DateTimeZone.UTC)); + // Assumption here is that you are here from the PUT which means that the service is RUNNING. + this.setStatus(DCAEServiceStatus.RUNNING); + } + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/dbthings/models/DCAEServiceTypeObject.java b/src/main/java/org/openecomp/dcae/inventory/dbthings/models/DCAEServiceTypeObject.java new file mode 100644 index 0000000..b57a28f --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/dbthings/models/DCAEServiceTypeObject.java @@ -0,0 +1,142 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.dbthings.models; + +import org.joda.time.DateTime; + +import java.util.List; + +/** + * POJO representation of a record in dcae_service_types table. + * + * Created by mhwang on 5/3/16. + */ +public class DCAEServiceTypeObject { + + private String typeId = null; + private String typeName = null; + private Integer typeVersion = null; + private String blueprintTemplate = null; + private String owner = null; + private List<String> vnfTypes = null; + private List<String> serviceIds = null; + private List<String> serviceLocations = null; + private String asdcServiceId = null; + private String asdcResourceId = null; + private DateTime created = null; + private DateTime deactivated = null; + + public String getTypeId() { + return typeId; + } + + public void setTypeId(String typeId) { + this.typeId = typeId; + } + + public String getTypeName() { + return typeName; + } + + public void setTypeName(String typeName) { + this.typeName = typeName; + } + + public Integer getTypeVersion() { + return typeVersion; + } + + public void setTypeVersion(Integer typeVersion) { + this.typeVersion = typeVersion; + } + + public String getBlueprintTemplate() { + return blueprintTemplate; + } + + public void setBlueprintTemplate(String blueprintTemplate) { + this.blueprintTemplate = blueprintTemplate; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public List<String> getVnfTypes() { + return vnfTypes; + } + + public void setVnfTypes(List<String> vnfTypes) { + this.vnfTypes = vnfTypes; + } + + public List<String> getServiceIds() { + return serviceIds; + } + + public void setServiceIds(List<String> serviceIds) { + this.serviceIds = serviceIds; + } + + public List<String> getServiceLocations() { + return serviceLocations; + } + + public void setServiceLocations(List<String> serviceLocations) { + this.serviceLocations = serviceLocations; + } + + public String getAsdcServiceId() { + return asdcServiceId; + } + + public void setAsdcServiceId(String asdcServiceId) { + this.asdcServiceId = asdcServiceId; + } + + public String getAsdcResourceId() { + return asdcResourceId; + } + + public void setAsdcResourceId(String asdcResourceId) { + this.asdcResourceId = asdcResourceId; + } + + public DateTime getCreated() { + return created; + } + + public void setCreated(DateTime created) { + this.created = created; + } + + public DateTime getDeactivated() { + return deactivated; + } + + public void setDeactivated(DateTime deactivated) { + this.deactivated = deactivated; + } +} diff --git a/src/main/java/org/openecomp/dcae/inventory/exceptions/DCAEControllerClientException.java b/src/main/java/org/openecomp/dcae/inventory/exceptions/DCAEControllerClientException.java new file mode 100644 index 0000000..eb30ae7 --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/exceptions/DCAEControllerClientException.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.exceptions; + +/** + * Created by mhwang on 5/13/16. + */ +public class DCAEControllerClientException extends RuntimeException { + + public DCAEControllerClientException(String message) { + super(message); + } + + public DCAEControllerClientException(Throwable e) { + super(e); + } + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/exceptions/DCAEControllerConnectionException.java b/src/main/java/org/openecomp/dcae/inventory/exceptions/DCAEControllerConnectionException.java new file mode 100644 index 0000000..2b9e6e7 --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/exceptions/DCAEControllerConnectionException.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.exceptions; + +/** + * Created by mhwang on 8/23/16. + */ +public class DCAEControllerConnectionException extends RuntimeException { + + public DCAEControllerConnectionException(String message) { + super(message); + } + + public DCAEControllerConnectionException(Throwable e) { + super(e); + } + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/exceptions/DCAEControllerTimeoutException.java b/src/main/java/org/openecomp/dcae/inventory/exceptions/DCAEControllerTimeoutException.java new file mode 100644 index 0000000..8aa9255 --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/exceptions/DCAEControllerTimeoutException.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.exceptions; + +/** + * Created by mhwang on 8/23/16. + */ +public class DCAEControllerTimeoutException extends RuntimeException { + + public DCAEControllerTimeoutException(String message) { + super(message); + } + + public DCAEControllerTimeoutException(Throwable e) { + super(e); + } + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/exceptions/DatabusControllerClientException.java b/src/main/java/org/openecomp/dcae/inventory/exceptions/DatabusControllerClientException.java new file mode 100644 index 0000000..6209521 --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/exceptions/DatabusControllerClientException.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.exceptions; + +/** + * Created by mhwang on 5/25/16. + */ +public class DatabusControllerClientException extends RuntimeException { + + public DatabusControllerClientException(String message) { + super(message); + } + + public DatabusControllerClientException(Throwable e) { + super(e); + } + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/exceptions/mappers/DBIExceptionMapper.java b/src/main/java/org/openecomp/dcae/inventory/exceptions/mappers/DBIExceptionMapper.java new file mode 100644 index 0000000..5dce2dd --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/exceptions/mappers/DBIExceptionMapper.java @@ -0,0 +1,82 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.exceptions.mappers; + +import org.openecomp.dcae.inventory.daos.InventoryDAOManager; +import io.swagger.api.ApiResponseMessage; +import org.skife.jdbi.v2.exceptions.DBIException; +import org.skife.jdbi.v2.exceptions.UnableToCreateStatementException; +import org.skife.jdbi.v2.exceptions.UnableToExecuteStatementException; +import org.skife.jdbi.v2.exceptions.UnableToObtainConnectionException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; + +/** + * Created by mhwang on 3/6/17. + * + * Responsible for handling DBIExceptions for Inventory which are raised by database client calls + * http://jdbi.org/apidocs/org/skife/jdbi/v2/exceptions/DBIException.html + * + * This class is intended to be extended to match on specific exceptions that are derived from DBIException + */ +public class DBIExceptionMapper<T extends DBIException> implements ExceptionMapper<T> { + + private final static Logger LOG = LoggerFactory.getLogger(DBIExceptionMapper.class); + + /** + * Upon a DBIException, this handler will attempt to re-initialize the Inventory's database connection + * and craft a specific message telling the client what to do. + * + * @param exception Derived class of DBIException + * @return Returns a Response with a status code of 502 with an ApiResponseMessage object + */ + @Override + public Response toResponse(T exception) { + LOG.error("", exception); + StringBuilder clientMessage = new StringBuilder("There is a database issue."); + + try { + InventoryDAOManager.getInstance().initialize(); + clientMessage.append(" Connection has been successfully reset. Please try again."); + } catch(Exception e) { + LOG.error(String.format("Failed to re-initialize database connection: %s", e.getMessage())); + clientMessage.append(" Connection reset attempt has failed. Please try again soon."); + } + + ApiResponseMessage response = new ApiResponseMessage(ApiResponseMessage.ERROR, clientMessage.toString()); + return Response.status(Response.Status.BAD_GATEWAY).entity(response).build(); + } + + // Here are the handlers for specific derived DBIException + + public final static class UnableToObtainConnectionExceptionMapper extends DBIExceptionMapper<UnableToObtainConnectionException> { + } + + public final static class UnableToCreateStatementExceptionMapper extends DBIExceptionMapper<UnableToCreateStatementException> { + } + + public final static class UnableToExecuteStatementExceptionMapper extends DBIExceptionMapper<UnableToExecuteStatementException> { + } + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/exceptions/mappers/DCAEControllerConnectionExceptionMapper.java b/src/main/java/org/openecomp/dcae/inventory/exceptions/mappers/DCAEControllerConnectionExceptionMapper.java new file mode 100644 index 0000000..76936e0 --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/exceptions/mappers/DCAEControllerConnectionExceptionMapper.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.exceptions.mappers; + +import org.openecomp.dcae.inventory.exceptions.DCAEControllerConnectionException; + +import javax.ws.rs.core.Response; + +/** + * Created by mhwang on 8/23/16. + */ +public class DCAEControllerConnectionExceptionMapper extends DCAEControllerExceptionMapper<DCAEControllerConnectionException> { + + @Override + protected Response.Status getStatus() { + return Response.Status.BAD_GATEWAY; + } + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/exceptions/mappers/DCAEControllerExceptionMapper.java b/src/main/java/org/openecomp/dcae/inventory/exceptions/mappers/DCAEControllerExceptionMapper.java new file mode 100644 index 0000000..b9ffda0 --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/exceptions/mappers/DCAEControllerExceptionMapper.java @@ -0,0 +1,41 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.exceptions.mappers; + +import io.swagger.api.ApiResponseMessage; + +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; + +/** + * Created by mhwang on 8/23/16. + */ +public abstract class DCAEControllerExceptionMapper<T extends RuntimeException> implements ExceptionMapper<T> { + + abstract protected Response.Status getStatus(); + + @Override + public Response toResponse(T e) { + ApiResponseMessage response = new ApiResponseMessage(ApiResponseMessage.ERROR, e.getMessage()); + return Response.status(this.getStatus()).entity(response).build(); + } + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/exceptions/mappers/DCAEControllerTimeoutExceptionMapper.java b/src/main/java/org/openecomp/dcae/inventory/exceptions/mappers/DCAEControllerTimeoutExceptionMapper.java new file mode 100644 index 0000000..9939aee --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/exceptions/mappers/DCAEControllerTimeoutExceptionMapper.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.exceptions.mappers; + +import org.openecomp.dcae.inventory.exceptions.DCAEControllerTimeoutException; + +import javax.ws.rs.core.Response; + +/** + * Created by mhwang on 8/23/16. + */ +public class DCAEControllerTimeoutExceptionMapper extends DCAEControllerExceptionMapper<DCAEControllerTimeoutException> { + + @Override + protected Response.Status getStatus() { + return Response.Status.GATEWAY_TIMEOUT; + } + +} diff --git a/src/main/java/org/openecomp/dcae/inventory/providers/NotFoundExceptionMapper.java b/src/main/java/org/openecomp/dcae/inventory/providers/NotFoundExceptionMapper.java new file mode 100644 index 0000000..0f54b46 --- /dev/null +++ b/src/main/java/org/openecomp/dcae/inventory/providers/NotFoundExceptionMapper.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * dcae-inventory + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dcae.inventory.providers; + +import io.swagger.api.ApiResponseMessage; +import io.swagger.api.NotFoundException; + +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; + +/** + * Created by mhwang on 5/18/16. + */ +public class NotFoundExceptionMapper implements ExceptionMapper<NotFoundException> { + + @Override + public Response toResponse(NotFoundException e) { + ApiResponseMessage entity = new ApiResponseMessage(e.getCode(), e.getMessage()); + return Response.status(Response.Status.NOT_FOUND).entity(entity).build(); + } + +} |