diff options
Diffstat (limited to 'appc-dispatcher/appc-dispatcher-common')
112 files changed, 5756 insertions, 0 deletions
diff --git a/appc-dispatcher/appc-dispatcher-common/.gitignore b/appc-dispatcher/appc-dispatcher-common/.gitignore new file mode 100644 index 000000000..09e3bc9b2 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/appc-dispatcher/appc-dispatcher-common/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-dispatcher-common/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/.gitignore b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/pom.xml b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/pom.xml new file mode 100644 index 000000000..8ab6095a6 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/pom.xml @@ -0,0 +1,41 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dispatcher-common</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-data-access-lib</artifactId> + <packaging>jar</packaging> + + <name>appc-data-access-lib</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + <scope>compile</scope> + </dependency> + </dependencies> +</project> diff --git a/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/AppcJdbcConnectionFactory.java b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/AppcJdbcConnectionFactory.java new file mode 100644 index 000000000..4b38e6610 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/AppcJdbcConnectionFactory.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.dao.util; + +import java.sql.Connection; +import java.sql.SQLException; + +public class AppcJdbcConnectionFactory implements JdbcConnectionFactory { + + private String schema; + + public void setSchema(String schema) { + this.schema = schema; + } + + public Connection openDbConnection() { + try { + return DBUtils.getConnection(schema); + } catch(SQLException e) { + throw new JdbcRuntimeException(Messages.EXP_APPC_JDBC_CONNECT.format(schema), e); + } + } + + public void closeDbConnection(Connection connection) { + try { + connection.close(); + } catch(SQLException e) { + throw new JdbcRuntimeException(Messages.EXP_APPC_JDBC_DISCONNECT.format(schema), e); + } + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/DBUtils.java b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/DBUtils.java new file mode 100644 index 000000000..294d948a0 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/DBUtils.java @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.dao.util; + +import java.sql.*; + +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; + +@Deprecated +public class DBUtils { + private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; + private static final Configuration configuration = ConfigurationFactory.getConfiguration(); + static { + try { + String driver = JDBC_DRIVER; + Class.forName(driver); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + + public static Connection getConnection(String schema) throws SQLException { + DriverManager.registerDriver(new com.mysql.jdbc.Driver()); + String dbURL = configuration.getProperty(String.format("org.openecomp.appc.db.url.%s", schema), ""); + String userName = configuration.getProperty(String.format("org.openecomp.appc.db.user.%s", schema), ""); + String password = configuration.getProperty(String.format("org.openecomp.appc.db.pass.%s", schema), ""); + return DriverManager.getConnection(dbURL, userName, password); + } + + public static boolean clearResources(ResultSet resultSet, PreparedStatement ptmt, Connection connection) { + boolean clearFlag = false; + try { + if (resultSet != null) + resultSet.close(); + if (ptmt != null) + ptmt.close(); + if (connection != null) + connection.close(); + clearFlag = true; + } catch (SQLException e) { + + } + return clearFlag; + + } + + /*public static DbLibService getDBLibService(){ + DbLibService dblibSvc = null; + BundleContext bctx = FrameworkUtil.getBundle(SvcLogicDblibStore.class).getBundleContext(); + ServiceReference sref = bctx.getServiceReference("org.openecomp.sdnc.sli.resource.dblib.DBResourceManager"); + if (sref == null) { +// LOG.warn("Could not find service reference for DBLIB service (org.openecomp.sdnc.sli.resource.dblib.DBResourceManager)"); + } + else { + dblibSvc = (DbLibService)bctx.getService(sref); + if (dblibSvc == null) + { +// LOG.warn("Could not find service reference for DBLIB service (org.openecomp.sdnc.sli.resource.dblib.DBResourceManager)"); + } + } + return dblibSvc; + }*/ +} diff --git a/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/DefaultJdbcConnectionFactory.java b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/DefaultJdbcConnectionFactory.java new file mode 100644 index 000000000..31db1e76e --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/DefaultJdbcConnectionFactory.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.dao.util; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +public abstract class DefaultJdbcConnectionFactory implements JdbcConnectionFactory { + + private static boolean driverRegistered = false; + + private String jdbcURL; + private String jdbcUserName; + private String jdbcPassword; + + public void setJdbcURL(String jdbcURL) { + this.jdbcURL = jdbcURL; + } + + public void setJdbcUserName(String jdbcUserName) { + this.jdbcUserName = jdbcUserName; + } + + public void setJdbcPassword(String jdbcPassword) { + this.jdbcPassword = jdbcPassword; + } + + + protected abstract void registedDriver() throws SQLException; + + @Override + public Connection openDbConnection() { + try { + if(!driverRegistered) { + registedDriver(); + driverRegistered = true; + } + return DriverManager.getConnection(jdbcURL, jdbcUserName, jdbcPassword); + } catch(SQLException e) { + throw new JdbcRuntimeException(Messages.EXP_JDBC_CONNECT.format(jdbcURL), e); + } + } + + @Override + public void closeDbConnection(Connection connection) { + try { + connection.close(); + } catch(SQLException e) { + throw new JdbcRuntimeException(Messages.EXP_JDBC_DISCONNECT.format(jdbcURL), e); + } + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/JdbcConnectionFactory.java b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/JdbcConnectionFactory.java new file mode 100644 index 000000000..3bd38320b --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/JdbcConnectionFactory.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.dao.util; + +import java.sql.Connection; + +public interface JdbcConnectionFactory { + + Connection openDbConnection(); + void closeDbConnection(Connection connection); +} diff --git a/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/JdbcRuntimeException.java b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/JdbcRuntimeException.java new file mode 100644 index 000000000..7b0682906 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/JdbcRuntimeException.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.dao.util; + +public class JdbcRuntimeException extends RuntimeException { + + public JdbcRuntimeException(String message) { + super(message); + } + + public JdbcRuntimeException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/Messages.java b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/Messages.java new file mode 100644 index 000000000..8c97188bd --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/Messages.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.dao.util; + +public enum Messages { + EXP_JDBC_CONNECT("Error connecting to JDBC URL [%s]."), + EXP_JDBC_DISCONNECT("Error closing JDBC connection to URL [%s]."), + EXP_APPC_JDBC_CONNECT("Error connecting to JDBC using properties for schema [%s]"), + EXP_APPC_JDBC_DISCONNECT("Error closing JDBC connection for schema [%s]."); + + private String message; + + Messages(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + + public String format(Object... s) { + return String.format(message, s); + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/.gitignore b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/pom.xml b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/pom.xml new file mode 100644 index 000000000..5722d18ea --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/pom.xml @@ -0,0 +1,36 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dispatcher-common</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>domain-model-lib</artifactId> + <packaging>bundle</packaging> + + <name>domain-model-lib</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Export-Package>org.openecomp.appc.domainmodel.lcm</Export-Package> + <Embed-Transitive>true</Embed-Transitive> + + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/ActionIdentifiers.java b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/ActionIdentifiers.java new file mode 100644 index 000000000..dc01e8f20 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/ActionIdentifiers.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.domainmodel.lcm; + + +public class ActionIdentifiers { + private String serviceInstanceId; + private String vnfId; + private String vnfcName; + private String vServerId; + + public String getServiceInstanceId() { + return serviceInstanceId; + } + + public void setServiceInstanceId(String serviceInstanceId) { + this.serviceInstanceId = serviceInstanceId; + } + + public String getVnfId() { + return vnfId; + } + + public void setVnfId(String vnfId) { + this.vnfId = vnfId; + } + + public String getVnfcName() { + return vnfcName; + } + + public void setVnfcName(String vnfcName) { + this.vnfcName = vnfcName; + } + + public String getVserverId() { + return vServerId; + } + + public void setvServerId(String vServerId) { + this.vServerId = vServerId; + } + + @Override + public String toString() { + return "ActionIdentifiers{" + + "serviceInstanceId='" + serviceInstanceId + '\'' + + ", vnfId='" + vnfId + '\'' + + ", vnfcName='" + vnfcName + '\'' + + ", vServerId='" + vServerId + '\'' + + '}'; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/CommonHeader.java b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/CommonHeader.java new file mode 100644 index 000000000..0819a58d5 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/CommonHeader.java @@ -0,0 +1,95 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.domainmodel.lcm; + +import java.util.Date; + + +public class CommonHeader { + + private Flags flags; + private Date timestamp; + private String apiVer; + private String originatorId; + private String requestId; + private String subRequestId; + + public Flags getFlags() { + return flags; + } + + public void setFlags(Flags flags) { + this.flags = flags; + } + + public Date getTimeStamp() { + return timestamp; + } + + public void setTimestamp(Date timestamp) { + this.timestamp = timestamp; + } + + public String getApiVer() { + return apiVer; + } + + public void setApiVer(String apiVer) { + this.apiVer = apiVer; + } + + public String getOriginatorId() { + return originatorId; + } + + public void setOriginatorId(String originatorId) { + this.originatorId = originatorId; + } + + public String getRequestId() { + return requestId; + } + + public void setRequestId(String requestId) { + this.requestId = requestId; + } + + public String getSubRequestId() { + return subRequestId; + } + + public void setSubRequestId(String subRequestId) { + this.subRequestId = subRequestId; + } + + @Override + public String toString() { + return "CommonHeader{" + + "flags=" + flags + + ", timestamp=" + timestamp + + ", apiVer='" + apiVer + '\'' + + ", originatorId='" + originatorId + '\'' + + ", requestId='" + requestId + '\'' + + ", subRequestId='" + subRequestId + '\'' + + '}'; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/Flags.java b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/Flags.java new file mode 100644 index 000000000..4f4ddba35 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/Flags.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.domainmodel.lcm; + + +public class Flags { + + private boolean force; + private int ttl; + private Mode mode; + + public boolean isForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } + + public int getTtl() { + return ttl; + } + + public void setTtl(int ttl) { + this.ttl = ttl; + } + + public Mode getMode() { + return mode; + } + + public void setMode(Mode mode) { + this.mode = mode; + } + + public void setMode(String mode) { + this.mode = Mode.valueOf(mode); + } + + @Override + public String toString() { + return "Flags{" + + "force=" + force + + ", ttl=" + ttl + + ", mode=" + mode + + '}'; + } + + public enum Mode { + EXCLUSIVE, + NORMAL + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/RequestContext.java b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/RequestContext.java new file mode 100644 index 000000000..c37262498 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/RequestContext.java @@ -0,0 +1,93 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.domainmodel.lcm; + +import java.util.HashMap; +import java.util.Map; + + +public class RequestContext { + + private CommonHeader commonHeader; + private ActionIdentifiers actionIdentifiers; + private VNFOperation action; + private String payload; + private Map<String, String> additionalContext; + + public CommonHeader getCommonHeader() { + return commonHeader; + } + + public void setCommonHeader(CommonHeader commonHeader) { + this.commonHeader = commonHeader; + } + + public ActionIdentifiers getActionIdentifiers() { + return actionIdentifiers; + } + + public void setActionIdentifiers(ActionIdentifiers actionIdentifiers) { + this.actionIdentifiers = actionIdentifiers; + } + + public VNFOperation getAction() { + return action; + } + + public void setAction(VNFOperation action) { + this.action = action; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + + public Map<String, String> getAdditionalContext() { + return additionalContext; + } + + public void setAdditionalContext(Map<String, String> additionalContext) { + this.additionalContext = additionalContext; + } + + public void addKeyValueToAdditionalContext(String key, String value ){ + if (this.additionalContext == null) { + this.additionalContext = new HashMap<>(); + } + this.additionalContext.put(key, value); + } + + @Override + public String toString() { + return "RequestContext{" + + "commonHeader=" + commonHeader + + ", actionIdentifiers=" + actionIdentifiers + + ", action=" + action + + ", payload='" + payload + '\'' + + ", additionalContext=" + additionalContext + + '}'; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/ResponseContext.java b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/ResponseContext.java new file mode 100644 index 000000000..81fba28ee --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/ResponseContext.java @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.domainmodel.lcm; + +import java.util.HashMap; +import java.util.Map; + + +public class ResponseContext { + private CommonHeader commonHeader; + private Status status; + private String payload; + private Map<String, String> additionalContext; + + public CommonHeader getCommonHeader() { + return commonHeader; + } + + public void setCommonHeader(CommonHeader commonHeader) { + this.commonHeader = commonHeader; + } + + public Status getStatus() { + return status; + } + + public void setStatus(Status status) { + this.status = status; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + + public Map<String, String> getAdditionalContext() { + return additionalContext; + } + + public void setAdditionalContext(Map<String, String> additionalContext) { + this.additionalContext = additionalContext; + } + + public void addKeyValueToAdditionalContext(String key, String value ){ + if (this.additionalContext == null) { + this.additionalContext = new HashMap<>(); + } + this.additionalContext.put(key, value); + } + + @Override + public String toString() { + return "ResponseContext{" + + "commonHeader=" + commonHeader + + ", status=" + status + + ", payload='" + payload + '\'' + + ", additionalContext=" + additionalContext + + '}'; + } + +} diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/RuntimeContext.java b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/RuntimeContext.java new file mode 100644 index 000000000..fd2bcffbf --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/RuntimeContext.java @@ -0,0 +1,97 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.domainmodel.lcm; + +import java.util.Date; + + +public class RuntimeContext { + + private RequestContext requestContext; + private ResponseContext responseContext; + private VNFContext vnfContext; + + //TODO move fields timeStart abd isLockAcquired to a better place + private Date timeStart; + private boolean isLockAcquired; + private String rpcName; + + public String getRpcName() { + return rpcName; + } + + public void setRpcName(String rpcName) { + this.rpcName = rpcName; + } + + public Date getTimeStart() { + return timeStart; + } + + public boolean isLockAcquired() { + return isLockAcquired; + } + + public void setIsLockAcquired(boolean isLockAcquired) { + this.isLockAcquired = isLockAcquired; + } + + public void setTimeStart(Date timeStart) { + this.timeStart = timeStart; + } + + public RequestContext getRequestContext() { + return requestContext; + } + + public void setRequestContext(RequestContext requestContext) { + this.requestContext = requestContext; + } + + public ResponseContext getResponseContext() { + return responseContext; + } + + public void setResponseContext(ResponseContext responseContext) { + this.responseContext = responseContext; + } + + public VNFContext getVnfContext() { + return vnfContext; + } + + public void setVnfContext(VNFContext vnfContext) { + this.vnfContext = vnfContext; + } + + @Override + public String toString() { + return "RuntimeContext{" + + "requestContext=" + requestContext + + ", responseContext=" + responseContext + + ", vnfContext=" + vnfContext + + ", timeStart=" + timeStart + + ", isLockAcquired=" + isLockAcquired + + ", rpcName='" + rpcName + '\'' + + '}'; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/Status.java b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/Status.java new file mode 100644 index 000000000..a5fbefa9c --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/Status.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.domainmodel.lcm; + + +public class Status { + + private int code; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String value) { + this.message = value; + } + + @Override + public String toString() { + return "Status{" + + "code='" + code + '\'' + + ", message='" + message + '\'' + + '}'; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFContext.java b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFContext.java new file mode 100644 index 000000000..4e2570139 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFContext.java @@ -0,0 +1,73 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.domainmodel.lcm; + + +public class VNFContext { + private String id; + private String type; + private String version; + private String status; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + + @Override + public String toString() { + return "VNFContext{" + + "id='" + id + '\'' + + ", type='" + type + '\'' + + ", version='" + version + '\'' + + ", status='" + status + '\'' + + '}'; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFOperation.java b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFOperation.java new file mode 100644 index 000000000..c61901eb3 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFOperation.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.domainmodel.lcm; + +public enum VNFOperation { + + Configure, Test, HealthCheck, Start, Terminate, Restart, Rebuild, Stop, ModifyConfig, Backup, Snapshot, + SoftwareUpload, LiveUpgrade, Rollback, Sync, Audit, Test_lic, Migrate, Evacuate, + Lock(true), Unlock(true), CheckLock(true); + + private boolean builtIn; + + VNFOperation(boolean builtIn) { + this.builtIn = builtIn; + } + + VNFOperation() { + this(false); + } + + /** + * Operations handled directly by the RequestHandler without further call to DG are built-in operations. + */ + public boolean isBuiltIn() { + return builtIn; + } + + public static VNFOperation findByString(String operationName) { + for(VNFOperation operation: VNFOperation.values()) { + if(operation.name().equals(operationName)) { + return operation; + } + } + return null; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/.gitignore b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/pom.xml b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/pom.xml new file mode 100644 index 000000000..cfa75c0b2 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/pom.xml @@ -0,0 +1,48 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dispatcher-common</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>execution-queue-management-lib</artifactId> + <packaging>bundle</packaging> + + <name>execution-queue-management-lib</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.att.eelf</groupId> + <artifactId>eelf-core</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Export-Package>org.openecomp.appc.executionqueue,org.openecomp.appc.executionqueue.impl</Export-Package> + <Import-Package>!groovy.lang,!javax.*,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.apache.commons.lang3,!org.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/ExecutionQueueService.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/ExecutionQueueService.java new file mode 100644 index 000000000..c93920083 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/ExecutionQueueService.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.executionqueue; + +import java.util.concurrent.TimeUnit; + +import org.openecomp.appc.exceptions.APPCException; + +public interface ExecutionQueueService<M extends Runnable> { + void putMessage(M message) throws APPCException; + void putMessage(M message, long timeout, TimeUnit unit) throws APPCException; + void registerMessageExpirationListener(MessageExpirationListener listener); +} diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/MessageExpirationListener.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/MessageExpirationListener.java new file mode 100644 index 000000000..cd5cbeab1 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/MessageExpirationListener.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.executionqueue; + +public interface MessageExpirationListener<M> { + void onMessageExpiration(M message); +} diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/helper/Util.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/helper/Util.java new file mode 100644 index 000000000..835e881aa --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/helper/Util.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.executionqueue.helper; + +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; + +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; + +public class Util { + + private static final Configuration configuration = ConfigurationFactory.getConfiguration(); + + public static int DEFAULT_QUEUE_SIZE = 10; + public static int DEFAULT_THREADPOOL_SIZE = 10; + + public static int getExecutionQueSize(){ + String sizeStr = configuration.getProperty("appc.dispatcher.executionqueue.backlog.size", String.valueOf(DEFAULT_QUEUE_SIZE)); + int size = DEFAULT_QUEUE_SIZE; + try{ + size = Integer.parseInt(sizeStr); + } + catch (NumberFormatException e){ + + } + return size; + } + + public static int getThreadPoolSize(){ + String sizeStr = configuration.getProperty("appc.dispatcher.executionqueue.threadpool.size", String.valueOf(DEFAULT_THREADPOOL_SIZE)); + int size = DEFAULT_THREADPOOL_SIZE; + try{ + size = Integer.parseInt(sizeStr); + } + catch (NumberFormatException e){ + + } + return size; + } + + public static ThreadFactory getThreadFactory(final boolean isDaemon){ + return new ThreadFactory() { + final ThreadFactory factory = Executors.defaultThreadFactory(); + public Thread newThread(Runnable r) { + Thread t = factory.newThread(r); + t.setDaemon(isDaemon); + return t; + } + }; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceFactory.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceFactory.java new file mode 100644 index 000000000..01e4358e9 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceFactory.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.executionqueue.impl; + +import org.openecomp.appc.executionqueue.ExecutionQueueService; + +public class ExecutionQueueServiceFactory { + + private static ExecutionQueueService executionQueueService =null; + + public static ExecutionQueueService getExecutionQueueService(){ + if(executionQueueService == null){ + synchronized (ExecutionQueueServiceFactory.class){ + if(executionQueueService == null) + executionQueueService = new ExecutionQueueServiceImpl(); + } + } + return executionQueueService; + } + +} diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceImpl.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceImpl.java new file mode 100644 index 000000000..c2be1b4ac --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceImpl.java @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.executionqueue.impl; + +import java.util.Calendar; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.executionqueue.ExecutionQueueService; +import org.openecomp.appc.executionqueue.MessageExpirationListener; +import org.openecomp.appc.executionqueue.impl.object.QueueMessage; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +public class ExecutionQueueServiceImpl<M extends Runnable> implements ExecutionQueueService<M> { + + private static final EELFLogger logger = + EELFManager.getInstance().getLogger(ExecutionQueueServiceImpl.class); + + ExecutionQueueServiceImpl(){ + + } + + @Override + public void putMessage(M message) throws APPCException { + this.putMessage(message,-1,null); + } + + @Override + public void putMessage(M message, long timeout, TimeUnit unit) throws APPCException{ + QueueMessage queueMessage = null; + + try { + Date expirationTime = calculateExpirationTime(timeout,unit); + queueMessage = new QueueMessage(message,expirationTime); + QueueManager queueManager = QueueManager.getInstance(); + boolean enqueueTask = queueManager.enqueueTask(queueMessage); + if(!enqueueTask){ + throw new APPCException("failed to put message in queue"); + } + } catch (Exception e) { + logger.error("Error in putMessage method of ExecutionQueueServiceImpl" + e.getMessage()); + throw new APPCException(e); + } + } + + @Override + public void registerMessageExpirationListener(MessageExpirationListener listener) { + QueueManager.getInstance().setListener(listener); + } + + private Date calculateExpirationTime(long timeToLive, TimeUnit unit) { + Date expirationTime = null; + if(timeToLive > 0){ + long currentTime = System.currentTimeMillis(); + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(currentTime + unit.toMillis(timeToLive)); + expirationTime = cal.getTime(); + } + return expirationTime; + } + +} diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/QueueManager.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/QueueManager.java new file mode 100644 index 000000000..2d4907fa1 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/QueueManager.java @@ -0,0 +1,108 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.executionqueue.impl; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; + +import org.openecomp.appc.executionqueue.MessageExpirationListener; +import org.openecomp.appc.executionqueue.helper.Util; +import org.openecomp.appc.executionqueue.impl.object.QueueMessage; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +public class QueueManager { + + private LinkedBlockingQueue<QueueMessage> queue; + + private MessageExpirationListener listener; + + private static int MAX_QUEUE_SIZE = Util.getExecutionQueSize(); + + private static int MAX_THREAD_SIZE = Util.getThreadPoolSize(); + + private ExecutorService messageExecutor; + + private static final EELFLogger logger = + EELFManager.getInstance().getLogger(QueueManager.class); + + private QueueManager(){ + init(); + } + + private static class QueueManagerHolder { + private static final QueueManager INSTANCE = new QueueManager(); + } + + public static QueueManager getInstance() { + return QueueManagerHolder.INSTANCE; + } + + private void init(){ + queue = new LinkedBlockingQueue(MAX_QUEUE_SIZE); + messageExecutor = Executors.newFixedThreadPool(MAX_THREAD_SIZE,Util.getThreadFactory(true)); + + for(int i=0;i<MAX_THREAD_SIZE;i++){ + messageExecutor.submit(new Runnable() { + @Override + public void run() { + while (true){ + try{ + QueueMessage queueMessage = queue.take(); + if(messageExpired(queueMessage)){ + logger.debug("Message expired "+ queueMessage.getMessage()); + if(listener != null){ + listener.onMessageExpiration(queueMessage.getMessage()); + } + else{ + logger.warn("Listener not available for expired message "); + } + } + else{ + queueMessage.getMessage().run(); + } + } catch (Exception e) { + logger.error("Error in startMessagePolling method of ExecutionQueueServiceImpl" + e.getMessage()); + } + } + } + }); + } + } + + public void setListener(MessageExpirationListener listener) { + this.listener = listener; + } + + public boolean enqueueTask(QueueMessage queueMessage) { + return queue.offer(queueMessage); + } + + private boolean messageExpired(QueueMessage queueMessage) { + if(queueMessage.getExpirationTime() != null){ + return queueMessage.getExpirationTime().getTime() < System.currentTimeMillis(); + } + return false; + } + +} diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/object/QueueMessage.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/object/QueueMessage.java new file mode 100644 index 000000000..bbf805871 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/object/QueueMessage.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.executionqueue.impl.object; + +import java.util.Date; + + +public class QueueMessage<M extends Runnable> { + M message; + Date expirationTime; + public QueueMessage(M message, Date expirationTime){ + this.message = message; + this.expirationTime = expirationTime; + } + + public M getMessage() { + return message; + } + + public Date getExpirationTime() { + return expirationTime; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/Listener.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/Listener.java new file mode 100644 index 000000000..294ae61b1 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/Listener.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.executionqueue; + +import org.openecomp.appc.executionqueue.MessageExpirationListener; + + +public class Listener implements MessageExpirationListener { + + boolean listenerExecuted = false; + + public boolean isListenerExecuted() { + return listenerExecuted; + } + + @Override + public void onMessageExpiration(Object message) { + listenerExecuted = true; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/Message.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/Message.java new file mode 100644 index 000000000..61c847842 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/Message.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.executionqueue; + + +public class Message implements Runnable { + + boolean runExecuted = false; + + public boolean isRunExecuted() { + return runExecuted; + } + + @Override + public void run() { + this.runExecuted = true; + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/TestExecutionQueueService.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/TestExecutionQueueService.java new file mode 100644 index 000000000..a8a20c10a --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/TestExecutionQueueService.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.executionqueue; + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.executionqueue.ExecutionQueueService; +import org.openecomp.appc.executionqueue.impl.ExecutionQueueServiceFactory; +import org.powermock.api.mockito.PowerMockito; + +import java.util.concurrent.TimeUnit; + + +public class TestExecutionQueueService { + + @Test + public void testPositiveFlow(){ + Message message = new Message(); + ExecutionQueueService service = ExecutionQueueServiceFactory.getExecutionQueueService(); + try { + service.putMessage(message); + waitFor(5000); + Assert.assertTrue(message.isRunExecuted()); + } catch (APPCException e) { + Assert.fail(e.toString()); + } + } + +// @Test + public void testTimeout(){ + ExecutionQueueService service = ExecutionQueueServiceFactory.getExecutionQueueService(); + Message message = new Message(); + Listener listener = new Listener(); + service.registerMessageExpirationListener(listener); + try { + service.putMessage(message,1, TimeUnit.MILLISECONDS); + waitFor(5000); + Assert.assertTrue(listener.isListenerExecuted()); + } catch (APPCException e) { + e.printStackTrace(); + } + } + + private void waitFor(long milliSeconds){ + try { + Thread.sleep(milliSeconds); + } catch (InterruptedException e) { + Assert.fail(e.toString()); + } + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/.gitignore b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/.gitignore new file mode 100644 index 000000000..09e3bc9b2 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/.gitignore b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/pom.xml b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/pom.xml new file mode 100644 index 000000000..c5560ab1f --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/pom.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>lock-manager-lib</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + + <artifactId>lock-manager-api</artifactId> + <packaging>bundle</packaging> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Export-Package>org.openecomp.appc.lockmanager.api</Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project>
\ No newline at end of file diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockException.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockException.java new file mode 100644 index 000000000..c5a94f9e1 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockException.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.lockmanager.api; + + +public class LockException extends Exception { + + public LockException(String message) { + super(message); + } + + public LockException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockManager.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockManager.java new file mode 100644 index 000000000..eebe5e24f --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockManager.java @@ -0,0 +1,69 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.lockmanager.api; + +/** + * Enables locking and unlocking of a resource by id. + * If the resource is locked, only lock owner can reacquire the lock or unlock the resource. + */ +public interface LockManager { + + /** + * Lock resource without timeout. Lock never expires. + * + * @param resource resource id + * @param owner lock owner id + * @return true - if lock is acquired, false - if the resource was already locked by the owner + * @throws LockException thrown if resource is already locked by other owner + */ + boolean acquireLock(String resource, String owner) throws LockException; + + /** + * Lock resource with timeout. After the timeout resource becomes unlocked. + * + * @param resource resource id + * @param owner lock owner id + * @param timeout in milliseconds, after this timeout lock will expire and resource becomes unlocked, + * timeout == 0 means that the lock never expires - same as call acquireLock() without timeout parameter + * @return true - if lock is acquired, false - if the resource was already locked by the owner + * @throws LockException thrown if resource is already locked by other owner + */ + boolean acquireLock(String resource, String owner, long timeout) throws LockException; + + /** + * Unlock resource. + * + * @param resource resource id + * @param owner lock owner id + * @throws LockException thrown if resource is locked by other owner + */ + void releaseLock(String resource, String owner) throws LockException; + + /** + * check resource lock status. + * + * @param resource resource id + */ + + boolean isLocked(String resource); + +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockRuntimeException.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockRuntimeException.java new file mode 100644 index 000000000..682cd6e27 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockRuntimeException.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.lockmanager.api; + +public class LockRuntimeException extends RuntimeException { + + public LockRuntimeException(String message) { + super(message); + } + + public LockRuntimeException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/.gitignore b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/pom.xml b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/pom.xml new file mode 100644 index 000000000..560661dfb --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/pom.xml @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>lock-manager-lib</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <name>lock-manager-features</name> + <artifactId>lock-manager-features</artifactId> + + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>lock-manager-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>lock-manager-impl</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> + <!--<plugin> + <!– launches the feature test, which validates that your karaf feature + can be installed inside of a karaf container. It doesn't validate that your + functionality works correctly, just that you have all of the dependent bundles + defined correctly. –> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.16</version> + <configuration> + <systemPropertyVariables> + <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId> + <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId> + <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version> + </systemPropertyVariables> + <dependenciesToScan> + <dependency>org.opendaylight.yangtools:features-test</dependency> + </dependenciesToScan> + <classpathDependencyExcludes> + <!– The dependencies which bring in AbstractDataBrokerTest class + brings in a second PaxExam container which results in the feature tests failing + with a message similar to: "ERROR o.ops4j.pax.exam.spi.PaxExamRuntime - Ambiguous + TestContainer ..." This excludes the container we don't want to use. –> + <classpathDependencyExcludes>org.ops4j.pax.exam:pax-exam-container-native</classpathDependencyExcludes> + </classpathDependencyExcludes> + </configuration> + </plugin>--> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + + <!-- Skipping ODL feature test --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <skipTests>true</skipTests> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/src/main/resources/features.xml b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/src/main/resources/features.xml new file mode 100644 index 000000000..ed51ca775 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/src/main/resources/features.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + 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========================================================= + --> + + +<features name="lock-manager-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + + <feature name='lock-manager' description="lock-manager" version='${project.version}'> + <bundle start-level="80" start="true">mvn:org.openecomp.appc/lock-manager-api/${project.version}</bundle> + <bundle start-level="85" start="true">mvn:org.openecomp.appc/lock-manager-impl/${project.version}</bundle> + </feature> + +</features> diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/.gitignore b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/.gitignore new file mode 100644 index 000000000..09e3bc9b2 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/pom.xml b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/pom.xml new file mode 100644 index 000000000..8ca41399a --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/pom.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>lock-manager-lib</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + + <artifactId>lock-manager-impl</artifactId> + <packaging>bundle</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>lock-manager-api</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + <version>${mysql.connector.version}</version> + <type>jar</type> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-data-access-lib</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.att.eelf</groupId> + <artifactId>eelf-core</artifactId> + <version>${eelf.version}</version> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Export-Service>org.openecomp.appc.lockmanager.api.LockManager</Export-Service> + <Import-Package>org.openecomp.appc.lockmanager.api.*,*</Import-Package> + <Private-Package>org.openecomp.appc.lockmanager.impl.*</Private-Package> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Import-Package>!org.apache.log,!org.apache.commons.logging,!groovy.lang,!javax.jms,!javax.mail.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.jasypt.*,*</Import-Package> + <Embed-Dependency>appc-common,appc-data-access-lib,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project>
\ No newline at end of file diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/inmemory/LockManagerInMemoryImpl.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/inmemory/LockManagerInMemoryImpl.java new file mode 100644 index 000000000..309e2790c --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/inmemory/LockManagerInMemoryImpl.java @@ -0,0 +1,130 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.lockmanager.impl.inmemory; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.openecomp.appc.lockmanager.api.LockException; +import org.openecomp.appc.lockmanager.api.LockManager; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + + +public class LockManagerInMemoryImpl implements LockManager { + + private static LockManagerInMemoryImpl instance = null; + private Map<String, LockValue> lockedVNFs; + + private static final EELFLogger debugLogger = EELFManager.getInstance().getDebugLogger(); + + private LockManagerInMemoryImpl() { + lockedVNFs = new ConcurrentHashMap<>(); + } + + public static LockManager getLockManager() { + if(instance == null) { + instance = new LockManagerInMemoryImpl(); + } + return instance; + } + + @Override + public boolean acquireLock(String resource, String owner) throws LockException { + return acquireLock(resource, owner, 0); + } + + @Override + public boolean acquireLock(String resource, String owner, long timeout) throws LockException { + debugLogger.debug("Try to acquire lock on resource " + resource + " with owner " + owner); + long now = System.currentTimeMillis(); + LockValue lockValue = lockedVNFs.get(resource); + if (lockValue != null) { + if (lockIsMine(lockValue, owner, now) || hasExpired(lockValue, now)) { + setExpirationTime(resource, owner, timeout, now); + debugLogger.debug("Locked successfully resource " + resource + " with owner " + owner + " for " + timeout + " ms"); + return hasExpired(lockValue, now); + } + else { + debugLogger.debug("Owner " + owner + " tried to lock resource " + resource + " but it is already locked by owner " + lockValue.getOwner()); + throw new LockException("Owner " + owner + " tried to lock resource " + resource + " but it is already locked by owner " + lockValue.getOwner()); + } + } + else { + setExpirationTime(resource, owner, timeout, now); + debugLogger.debug("Locked successfully resource " + resource + " with owner " + owner + " for " + timeout + " ms"); + return true; + } + } + + @Override + public void releaseLock(String resource, String owner) throws LockException { + debugLogger.debug("Try to release lock on resource " + resource + " with owner " + owner); + long now = System.currentTimeMillis(); + LockValue lockValue = lockedVNFs.get(resource); + if (lockValue != null) { + if (!hasExpired(lockValue, now)) { + if (isOwner(lockValue, owner)) { + debugLogger.debug("Unlocked successfully resource " + resource + " with owner " + owner); + lockedVNFs.remove(resource); + } + else { + debugLogger.debug("Unlock failed. Tried to release lock on resource " + resource + " from owner " + owner + " but it is held by a different owner"); + throw new LockException("Unlock failed. Tried to release lock on resource " + resource + " from owner " + owner + " but it is held by a different owner"); + } + } + else { + lockedVNFs.remove(resource); + debugLogger.debug("Unlock failed. lock on resource " + resource + " has expired"); + throw new LockException("Unlock failed. lock on resource " + resource + " has expired"); + } + + } + else { + debugLogger.debug("Tried to release lock on resource " + resource + " from owner " + owner + " but there is not lock on this resource"); + throw new LockException("Tried to release lock on resource " + resource + " from owner " + owner + " but there is not lock on this resource"); + } + } + + @Override + public boolean isLocked(String resource) { + return lockedVNFs.get(resource)!=null?true:false; + } + + private boolean lockIsMine(LockValue lockValue, String owner, long now) { + return isOwner(lockValue, owner) && !hasExpired(lockValue, now); + } + + private boolean isOwner(LockValue lockValue, String owner) { + return lockValue.getOwner() != null && lockValue.getOwner().equals(owner); + } + + private boolean hasExpired(LockValue lockValue, long now) { + return (lockValue.getExpirationTime() != 0 && now > lockValue.getExpirationTime()); + } + + private void setExpirationTime(String resource, String owner, long timeout, long now) { + long expirationTime = timeout == 0 ? 0 : now + timeout; + LockValue lockValue = new LockValue(owner, expirationTime); + lockedVNFs.put(resource, lockValue); + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/inmemory/LockValue.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/inmemory/LockValue.java new file mode 100644 index 000000000..abdd494d9 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/inmemory/LockValue.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.lockmanager.impl.inmemory; + + +public class LockValue { + + private String owner; + private long expirationTime; + + LockValue(String owner, long expirationTime) { + this.owner = owner; + this.expirationTime = expirationTime; + } + + String getOwner() { + return owner; + } + + long getExpirationTime() { + return expirationTime; + } + +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/JdbcLockManager.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/JdbcLockManager.java new file mode 100644 index 000000000..97a5cc339 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/JdbcLockManager.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.lockmanager.impl.sql; + +import java.sql.Connection; + +import org.openecomp.appc.dao.util.JdbcConnectionFactory; +import org.openecomp.appc.lockmanager.api.LockManager; + +public abstract class JdbcLockManager implements LockManager { + + private static final String DEF_TABLE_LOCK_MANAGEMENT = "LOCK_MANAGEMENT"; + + private JdbcConnectionFactory connectionFactory; + protected String tableName = DEF_TABLE_LOCK_MANAGEMENT; + + public void setConnectionFactory(JdbcConnectionFactory connectionFactory) { + this.connectionFactory = connectionFactory; + } + + public void setTableName(String tableName) { + this.tableName = tableName; + } + + protected Connection openDbConnection() { + return connectionFactory.openDbConnection(); + } + + protected void closeDbConnection(Connection connection) { + connectionFactory.closeDbConnection(connection); + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/Messages.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/Messages.java new file mode 100644 index 000000000..0399726b5 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/Messages.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.lockmanager.impl.sql; + +public enum Messages { + + ERR_NULL_LOCK_OWNER("Cannot acquire lock for resource [%s]: lock owner must be specified"), + ERR_LOCK_LOCKED_BY_OTHER("Cannot lock resource [%s] for [%s]: already locked by [%s]"), + ERR_UNLOCK_NOT_LOCKED("Error unlocking resource [%s]: resource is not locked"), + ERR_UNLOCK_LOCKED_BY_OTHER("Error unlocking resource [%s] by [%s]: resource is locked by [%s]"), + EXP_LOCK("Error locking resource [%s]."), + EXP_UNLOCK("Error unlocking resource [%s]."), + ; + + private String message; + + Messages(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + + public String format(Object... s) { + return String.format(message, s); + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/MySqlConnectionFactory.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/MySqlConnectionFactory.java new file mode 100644 index 000000000..4ccd0c453 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/MySqlConnectionFactory.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.lockmanager.impl.sql; + +import java.sql.DriverManager; +import java.sql.SQLException; + +import org.openecomp.appc.dao.util.DefaultJdbcConnectionFactory; + +public class MySqlConnectionFactory extends DefaultJdbcConnectionFactory { + + protected void registedDriver() throws SQLException { + DriverManager.registerDriver(new com.mysql.jdbc.Driver()); + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/LockRecord.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/LockRecord.java new file mode 100644 index 000000000..d66804488 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/LockRecord.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.lockmanager.impl.sql.optimistic; + +class LockRecord { + + private String resource; + private String owner; + private long updated; + private long timeout; + private long ver; + + LockRecord(String resource) { + this.resource = resource; + } + + public String getResource() { + return resource; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public long getUpdated() { + return updated; + } + + public void setUpdated(long updated) { + this.updated = updated; + } + + public long getTimeout() { + return timeout; + } + + public void setTimeout(long timeout) { + this.timeout = timeout; + } + + public long getVer() { + return ver; + } + + public void setVer(long ver) { + this.ver = ver; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/MySqlLockManager.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/MySqlLockManager.java new file mode 100644 index 000000000..e80133620 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/MySqlLockManager.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.lockmanager.impl.sql.optimistic; + +import java.sql.SQLException; + +public class MySqlLockManager extends SqlLockManager { + + @Override + protected boolean isDuplicatePkError(SQLException e) { + return (e.getErrorCode() == 1062); + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/SqlLockManager.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/SqlLockManager.java new file mode 100644 index 000000000..52c75d2b2 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/SqlLockManager.java @@ -0,0 +1,263 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.lockmanager.impl.sql.optimistic; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.openecomp.appc.lockmanager.api.LockException; +import org.openecomp.appc.lockmanager.api.LockRuntimeException; +import org.openecomp.appc.lockmanager.impl.sql.JdbcLockManager; +import org.openecomp.appc.lockmanager.impl.sql.Messages; + +abstract class SqlLockManager extends JdbcLockManager { + + private static final String SQL_LOAD_LOCK_RECORD = "SELECT * FROM %s WHERE RESOURCE_ID=?"; + private static final String SQL_INSERT_LOCK_RECORD = "INSERT INTO %s (RESOURCE_ID, OWNER_ID, UPDATED, TIMEOUT, VER) VALUES (?, ?, ?, ?, ?)"; + private static final String SQL_UPDATE_LOCK_RECORD = "UPDATE %s SET OWNER_ID=?, UPDATED=?, TIMEOUT=?, VER=? WHERE RESOURCE_ID=? AND VER=?"; +// private static final String SQL_DELETE_LOCK_RECORD = "DELETE FROM %s WHERE RESOURCE_ID=? AND VER=?"; + private static final String SQL_CURRENT_TIMESTAMP = "SELECT CURRENT_TIMESTAMP()"; + + private String sqlLoadLockRecord; + private String sqlInsertLockRecord; + private String sqlUpdateLockRecord; +// private String sqlDeleteLockRecord; + + @Override + public boolean acquireLock(String resource, String owner) throws LockException { + return acquireLock(resource, owner, 0); + } + + @Override + public boolean acquireLock(String resource, String owner, long timeout) throws LockException { + if(owner == null) { + throw new LockRuntimeException(Messages.ERR_NULL_LOCK_OWNER.format(resource)); + } + boolean res = false; + Connection connection = openDbConnection(); + try { + res = lockResource(connection, resource, owner, timeout); + } finally { + closeDbConnection(connection); + } + return res; + } + + @Override + public void releaseLock(String resource, String owner) throws LockException { + Connection connection = openDbConnection(); + try { + unlockResource(connection, resource, owner); + } finally { + closeDbConnection(connection); + } + } + + @Override + public boolean isLocked(String resource) { + Connection connection=openDbConnection(); + try { + LockRecord lockRecord=loadLockRecord(connection,resource); + if(lockRecord==null){ + return false; + }else{ + if(lockRecord.getOwner()==null){ + return false; + }else if(isLockExpired(lockRecord, connection)){ + return false; + }else{ + return true; + } + } + } catch (SQLException e) { + throw new LockRuntimeException(Messages.EXP_LOCK.format(resource)); + }finally { + closeDbConnection(connection); + } + } + + private boolean lockResource(Connection connection, String resource, String owner, long timeout) throws LockException { + try { + boolean res = false; + LockRecord lockRecord = loadLockRecord(connection, resource); + if(lockRecord != null) { + // lock record already exists + String currentOwner = lockRecord.getOwner(); + if(currentOwner != null) { + if(isLockExpired(lockRecord, connection)) { + currentOwner = null; + } else if(!owner.equals(currentOwner)) { + throw new LockException(Messages.ERR_LOCK_LOCKED_BY_OTHER.format(resource, owner, currentOwner)); + } + } + // set new owner on the resource lock record + if(!updateLockRecord(connection, resource, owner, timeout, lockRecord.getVer())) { + // try again - maybe same owner updated the record + lockResource(connection, resource, owner, timeout); + } + if(currentOwner == null) { + // no one locked the resource before + res = true; + } + } else { + // resource record does not exist in lock table => create new record + try { + addLockRecord(connection, resource, owner, timeout); + res = true; + } catch(SQLException e) { + if(isDuplicatePkError(e)) { + // try again - maybe same owner inserted the record + lockResource(connection, resource, owner, timeout); + } else { + throw e; + } + } + } + return res; + } catch(SQLException e) { + throw new LockRuntimeException(Messages.EXP_LOCK.format(resource), e); + } + } + + protected boolean isDuplicatePkError(SQLException e) { + return e.getSQLState().startsWith("23"); + } + + private void unlockResource(Connection connection, String resource, String owner) throws LockException { + try { + LockRecord lockRecord = loadLockRecord(connection, resource); + if(lockRecord != null) { + // check if expired + if(isLockExpired(lockRecord, connection)) { + // lock is expired => no lock + lockRecord = null; + } + } + if((lockRecord == null) || (lockRecord.getOwner() == null)) { + // resource is not locked + throw new LockException(Messages.ERR_UNLOCK_NOT_LOCKED.format(resource)); + } + String currentOwner = lockRecord.getOwner(); + if(!owner.equals(currentOwner)) { + throw new LockException(Messages.ERR_UNLOCK_LOCKED_BY_OTHER.format(resource, owner, currentOwner)); + } + if (!updateLockRecord(connection, resource, null, 0, lockRecord.getVer())) { + unlockResource(connection, resource, owner); + } + // TODO delete record from table on lock release? +// deleteLockRecord(connection, resource, lockRecord.getVer()); + } catch(SQLException e) { + throw new LockRuntimeException(Messages.EXP_UNLOCK.format(resource), e); + } + } + + protected LockRecord loadLockRecord(Connection connection, String resource) throws SQLException { + LockRecord res = null; + if(sqlLoadLockRecord == null) { + sqlLoadLockRecord = String.format(SQL_LOAD_LOCK_RECORD, tableName); + } + try(PreparedStatement statement = connection.prepareStatement(sqlLoadLockRecord)) { + statement.setString(1, resource); + try(ResultSet resultSet = statement.executeQuery()) { + if(resultSet.next()) { + res = new LockRecord(resource); + res.setOwner(resultSet.getString(2)); + res.setUpdated(resultSet.getLong(3)); + res.setTimeout(resultSet.getLong(4)); + res.setVer(resultSet.getLong(5)); + } + } + } + return res; + } + + protected void addLockRecord(Connection connection, String resource, String owner, long timeout) throws SQLException { + if(sqlInsertLockRecord == null) { + sqlInsertLockRecord = String.format(SQL_INSERT_LOCK_RECORD, tableName); + } + try(PreparedStatement statement = connection.prepareStatement(sqlInsertLockRecord)) { + statement.setString(1, resource); + statement.setString(2, owner); + statement.setLong(3, getCurrentTime(connection)); + statement.setLong(4, timeout); + statement.setLong(5, 1); + statement.executeUpdate(); + } + } + + protected boolean updateLockRecord(Connection connection, String resource, String owner, long timeout, long ver) throws SQLException { + if(sqlUpdateLockRecord == null) { + sqlUpdateLockRecord = String.format(SQL_UPDATE_LOCK_RECORD, tableName); + } + try(PreparedStatement statement = connection.prepareStatement(sqlUpdateLockRecord)) { + long newVer = (ver >= Long.MAX_VALUE) ? 1 : (ver + 1); + statement.setString(1, owner); + statement.setLong(2, getCurrentTime(connection)); + statement.setLong(3, timeout); + statement.setLong(4, newVer); + statement.setString(5, resource); + statement.setLong(6, ver); + return (statement.executeUpdate() != 0); + } + } + +// protected void deleteLockRecord(Connection connection, String resource, long ver) throws SQLException { +// if(sqlDeleteLockRecord == null) { +// sqlDeleteLockRecord = String.format(SQL_DELETE_LOCK_RECORD, tableName); +// } +// try(PreparedStatement statement = connection.prepareStatement(sqlDeleteLockRecord)) { +// statement.setString(1, resource); +// statement.setLong(2, ver); +// statement.executeUpdate(); +// } +// } + + private boolean isLockExpired(LockRecord lockRecord, Connection connection) throws SQLException { + long timeout = lockRecord.getTimeout(); + if(timeout == 0) { + return false; + } + long updated = lockRecord.getUpdated(); + long now = getCurrentTime(connection); + long expiration = updated + timeout; + return (now > expiration); + } + + private long getCurrentTime(Connection connection) throws SQLException { + long res = -1; + if(connection != null) { + try(PreparedStatement statement = connection.prepareStatement(SQL_CURRENT_TIMESTAMP)) { + try(ResultSet resultSet = statement.executeQuery()) { + if(resultSet.next()) { + res = resultSet.getTimestamp(1).getTime(); + } + } + } + } + if(res == -1) { + res = System.currentTimeMillis(); + } + return res; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..6ec23eeb0 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + 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========================================================= + --> + + +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> + + <!--<bean id="lockManagerInMemoryBean" class="org.openecomp.appc.lockmanager.impl.inmemory.LockManagerInMemoryImpl" factory-method="getLockManager" scope="singleton"/>--> + <!--<service id="lockManagerInMemoryService" interface="org.openecomp.appc.lockmanager.api.LockManager" ref="lockManagerInMemoryBean"/>--> + + <service id="lockManagerMySqlOptimisticService" interface="org.openecomp.appc.lockmanager.api.LockManager"> + <bean class="org.openecomp.appc.lockmanager.impl.sql.optimistic.MySqlLockManager"> + <property name="connectionFactory"> + <bean class="org.openecomp.appc.dao.util.AppcJdbcConnectionFactory"> + <property name="schema" value="sdnctl"/> + </bean> + </property> + <property name="tableName" value="VNF_LOCK_MANAGEMENT"/> + </bean> + </service> +</blueprint> diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/api/LockManagerBaseTests.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/api/LockManagerBaseTests.java new file mode 100644 index 000000000..47e27f79d --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/api/LockManagerBaseTests.java @@ -0,0 +1,167 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.lockmanager.api; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openecomp.appc.lockmanager.api.LockException; +import org.openecomp.appc.lockmanager.api.LockManager; + +public abstract class LockManagerBaseTests { + + protected enum Resource {Resource1, Resource2}; + protected enum Owner {A, B}; + + protected LockManager lockManager; + + @Before + public void beforeTest() { + lockManager = createLockManager(); + } + + protected abstract LockManager createLockManager(); + + @Test + public void testAcquireLock() throws LockException { + boolean lockRes = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()); + try { + Assert.assertTrue(lockRes); + } finally { + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + } + } + + @Test + public void testAcquireLock_AlreadyLockedBySameOwner() throws LockException { + boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()); + try { + Assert.assertTrue(lockRes1); + boolean lockRes2 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()); + Assert.assertFalse(lockRes2); + } finally { + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + } + } + + @Test(expected = LockException.class) + public void testAcquireLock_AlreadyLockedByOtherOwner() throws LockException { + String owner2 = "B"; + boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()); + try { + Assert.assertTrue(lockRes1); + boolean lockRes2 = lockManager.acquireLock(Resource.Resource1.name(), owner2); + Assert.assertFalse(lockRes2); + } finally { + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + } + } + + @Test + public void testAcquireLock_LockDifferentResources() throws LockException { + boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()); + try { + Assert.assertTrue(lockRes1); + boolean lockRes2 = lockManager.acquireLock(Resource.Resource2.name(), Owner.B.name()); + try { + Assert.assertTrue(lockRes2); + } finally { + lockManager.releaseLock(Resource.Resource2.name(), Owner.B.name()); + } + } finally { + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + } + } + + @Test(expected = LockException.class) + public void testReleaseLock_NotLockedResource() throws LockException { + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + } + + @Test(expected = LockException.class) + public void testReleaseLock_LockedByOtherOwnerResource() throws LockException { + boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()); + try { + Assert.assertTrue(lockRes1); + lockManager.releaseLock(Resource.Resource1.name(), Owner.B.name()); + } finally { + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + } + } + + @Test(expected = LockException.class) + public void testAcquireLock_LockExpired() throws LockException, InterruptedException { + boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name(), 50); + Assert.assertTrue(lockRes1); + Thread.sleep(1000); + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + } + + @Test + public void testAcquireLock_OtherLockExpired() throws LockException, InterruptedException { + boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name(), 50); + Assert.assertTrue(lockRes1); + Thread.sleep(1000); + boolean lockRes2 = lockManager.acquireLock(Resource.Resource1.name(), Owner.B.name()); + try { + Assert.assertTrue(lockRes2); + }finally { + lockManager.releaseLock(Resource.Resource1.name(), Owner.B.name()); + } + } + + @Test + public void testIsLocked_WhenLocked() throws LockException, InterruptedException { + boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name(), 50); + try { + Assert.assertTrue(lockManager.isLocked(Resource.Resource1.name())); + }finally { + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + } + } + + + @Test(expected = LockException.class) + public void testIsLocked_LockExpired() throws LockException, InterruptedException { + boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name(), 50); + Assert.assertTrue(lockRes1); + Assert.assertTrue(lockManager.isLocked(Resource.Resource1.name())); + Thread.sleep(1000); + try { + Assert.assertFalse(lockManager.isLocked(Resource.Resource1.name())); + }finally { + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + } + } + + @Test + public void testIsLocked_LockReleased() throws LockException, InterruptedException { + boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name(), 50); + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + Assert.assertFalse(lockManager.isLocked(Resource.Resource1.name())); + } + + @Test + public void testIsLocked_NoLock() throws LockException, InterruptedException { + Assert.assertFalse(lockManager.isLocked(Resource.Resource1.name())); + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/inmemory/LockManagerInMemoryImplTest.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/inmemory/LockManagerInMemoryImplTest.java new file mode 100644 index 000000000..99faec23d --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/inmemory/LockManagerInMemoryImplTest.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.lockmanager.impl.inmemory; + +import org.openecomp.appc.lockmanager.api.LockManager; +import org.openecomp.appc.lockmanager.api.LockManagerBaseTests; +import org.openecomp.appc.lockmanager.impl.inmemory.LockManagerInMemoryImpl; + + +public class LockManagerInMemoryImplTest extends LockManagerBaseTests { + + @Override + protected LockManager createLockManager() { + return LockManagerInMemoryImpl.getLockManager(); + } + +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/MySqlLockManagerBaseTests.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/MySqlLockManagerBaseTests.java new file mode 100644 index 000000000..da5607819 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/MySqlLockManagerBaseTests.java @@ -0,0 +1,93 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.lockmanager.impl.sql; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.appc.dao.util.DefaultJdbcConnectionFactory; +import org.openecomp.appc.lockmanager.api.LockManager; +import org.openecomp.appc.lockmanager.api.LockManagerBaseTests; +import org.openecomp.appc.lockmanager.impl.sql.JdbcLockManager; +import org.openecomp.appc.lockmanager.impl.sql.MySqlConnectionFactory; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +public abstract class MySqlLockManagerBaseTests extends LockManagerBaseTests { + + private static final boolean USE_REAL_DB = Boolean.getBoolean("lockmanager.tests.useRealDb"); + private static final String TABLE_LOCK_MANAGEMENT = "TEST_LOCK_MANAGEMENT"; + private static final String JDBC_URL = System.getProperty("lockmanager.tests.jdbcUrl", "jdbc:mysql://192.168.1.2/test"); + private static final String JDBC_USERNAME = System.getProperty("lockmanager.tests.jdbcUsername", "test"); + private static final String JDBC_PASSWORD = System.getProperty("lockmanager.tests.jdbcPassword", "123456"); + + protected static final int CONCURRENT_TEST_WAIT_TIME = 10; // secs + + @Rule + public TestName testName = new TestName(); + + @Override + protected LockManager createLockManager() { + JdbcLockManager jdbcLockManager = createJdbcLockManager(USE_REAL_DB); + DefaultJdbcConnectionFactory connectionFactory = new MySqlConnectionFactory(); + connectionFactory.setJdbcURL(JDBC_URL); + connectionFactory.setJdbcUserName(JDBC_USERNAME); + connectionFactory.setJdbcPassword(JDBC_PASSWORD); + jdbcLockManager.setConnectionFactory(connectionFactory); + jdbcLockManager.setTableName(TABLE_LOCK_MANAGEMENT); + System.out.println("=> Running LockManager test [" + jdbcLockManager.getClass().getName() + "." + testName.getMethodName() + "]" + (USE_REAL_DB ? ". JDBC URL is [" + JDBC_URL + "]" : "")); + clearTestLocks(jdbcLockManager); + return jdbcLockManager; + } + + protected abstract JdbcLockManager createJdbcLockManager(boolean useRealDb); + + protected boolean setSynchronizer(Synchronizer synchronizer) { + if(!(lockManager instanceof SynchronizerReceiver)) { + System.err.println("Skipping concurrency test [" + testName.getMethodName() + "] for LockManager of type " + lockManager.getClass()); + return false; + } + ((SynchronizerReceiver)lockManager).setSynchronizer(synchronizer); + return true; + } + + private static final String SQL_DELETE_LOCK_RECORD = String.format("DELETE FROM %s WHERE RESOURCE_ID=?", TABLE_LOCK_MANAGEMENT); + private void clearTestLocks(JdbcLockManager jdbcLockManager) { + Connection connection = jdbcLockManager.openDbConnection(); + if(connection == null) { + return; + } + try { + for(Resource resource: Resource.values()) { + try(PreparedStatement statement = connection.prepareStatement(SQL_DELETE_LOCK_RECORD)) { + statement.setString(1, resource.name()); + statement.executeUpdate(); + } + } + } catch(SQLException e) { + throw new RuntimeException("Cannot clear test resources in table", e); + } finally { + jdbcLockManager.closeDbConnection(connection); + } + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/Synchronizer.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/Synchronizer.java new file mode 100644 index 000000000..8d1f0bbfd --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/Synchronizer.java @@ -0,0 +1,80 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.lockmanager.impl.sql; + +public class Synchronizer { + + private int participantNo; + private int participantCount; + + public Synchronizer(int participantNo) { + this.participantNo = participantNo; + } + + public int getParticipantCount() { + return participantCount; + } + + public void postLoadLockRecord(String resource, String owner) { + synchronized(this) { + waitForAllParticipants(this, participantNo, ++participantCount); + } + } + + public void preAddLockRecord(String resource, String owner) { + } + + public void postAddLockRecord(String resource, String owner) { + } + + public void preUpdateLockRecord(String resource, String owner) { + } + + public void postUpdateLockRecord(String resource, String owner) { + } + + public void releaseWait() { + synchronized(this) { + this.notifyAll(); + } + } + + protected void waitOn(Object obj, long timeout) { + try { + obj.wait(timeout); + } catch(InterruptedException e) { + throw new RuntimeException(e); + } + } + + protected void waitOn(Object obj) { + waitOn(obj, 0); + } + + protected void waitForAllParticipants(Object waitObj, int totalParticipantsNo, int currentParticipantsNo) { + if(totalParticipantsNo > currentParticipantsNo) { + waitOn(waitObj); + } else { + waitObj.notifyAll(); + } + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/SynchronizerReceiver.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/SynchronizerReceiver.java new file mode 100644 index 000000000..945fed10b --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/SynchronizerReceiver.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.lockmanager.impl.sql; + +public interface SynchronizerReceiver { + + void setSynchronizer(Synchronizer synchronizer); +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/MySqlLockManagerMock.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/MySqlLockManagerMock.java new file mode 100644 index 000000000..3e6a236ba --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/MySqlLockManagerMock.java @@ -0,0 +1,132 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.lockmanager.impl.sql.optimistic; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.openecomp.appc.lockmanager.impl.sql.Synchronizer; +import org.openecomp.appc.lockmanager.impl.sql.SynchronizerReceiver; +import org.openecomp.appc.lockmanager.impl.sql.optimistic.LockRecord; +import org.openecomp.appc.lockmanager.impl.sql.optimistic.MySqlLockManager; + +class MySqlLockManagerMock extends MySqlLockManager implements SynchronizerReceiver { + + private final ConcurrentMap<String, LockRecord> locks = new ConcurrentHashMap<>(); + private boolean useReal; + private Synchronizer synchronizer; + + MySqlLockManagerMock(boolean useReal) { + this.useReal = useReal; + } + + @Override + public void setSynchronizer(Synchronizer synchronizer) { + this.synchronizer = synchronizer; + } + + @Override + protected Connection openDbConnection() { + if(useReal) { + return super.openDbConnection(); + } + return null; + } + + @Override + protected void closeDbConnection(Connection connection) { + if(useReal) { + super.closeDbConnection(connection); + } + } + + @Override + protected LockRecord loadLockRecord(Connection connection, String resource) throws SQLException { + LockRecord res; + if(useReal) { + res = super.loadLockRecord(connection, resource); + } else { + res = locks.get(resource); + } + if(synchronizer != null) { + synchronizer.postLoadLockRecord(resource, (res == null) ? null : res.getOwner()); + } + return res; + } + + @Override + protected void addLockRecord(Connection connection, String resource, String owner, long timeout) throws SQLException { + if(synchronizer != null) { + synchronizer.preAddLockRecord(resource, owner); + } + try { + if(useReal) { + super.addLockRecord(connection, resource, owner, timeout); + return; + } + LockRecord lockRecord = new LockRecord(resource); + lockRecord.setOwner(owner); + lockRecord.setUpdated(System.currentTimeMillis()); + lockRecord.setTimeout(timeout); + lockRecord.setVer(1); + LockRecord prevLockRecord = locks.putIfAbsent(resource, lockRecord); + if(prevLockRecord != null) { + // simulate unique constraint violation + throw new SQLException("Duplicate PK exception", "23000", 1062); + } + } finally { + if(synchronizer != null) { + synchronizer.postAddLockRecord(resource, owner); + } + } + } + + @Override + protected boolean updateLockRecord(Connection connection, String resource, String owner, long timeout, long ver) throws SQLException { + if(synchronizer != null) { + synchronizer.preUpdateLockRecord(resource, owner); + } + try { + if(useReal) { + return super.updateLockRecord(connection, resource, owner, timeout, ver); + } + LockRecord lockRecord = loadLockRecord(connection, resource); + synchronized(lockRecord) { + // should be atomic operation + if(ver != lockRecord.getVer()) { + return false; + } + lockRecord.setOwner(owner); + lockRecord.setUpdated(System.currentTimeMillis()); + lockRecord.setTimeout(timeout); + lockRecord.setVer(ver + 1); + } + return true; + } finally { + if(synchronizer != null) { + synchronizer.postUpdateLockRecord(resource, owner); + } + } + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/TestMySqlLockManager.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/TestMySqlLockManager.java new file mode 100644 index 000000000..6106dd84b --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/TestMySqlLockManager.java @@ -0,0 +1,227 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.lockmanager.impl.sql.optimistic; + +import org.junit.Assert; +import org.junit.Test; +import org.openecomp.appc.lockmanager.api.LockException; +import org.openecomp.appc.lockmanager.impl.sql.JdbcLockManager; +import org.openecomp.appc.lockmanager.impl.sql.MySqlLockManagerBaseTests; +import org.openecomp.appc.lockmanager.impl.sql.Synchronizer; + +import java.util.concurrent.*; + +public class TestMySqlLockManager extends MySqlLockManagerBaseTests { + + @Override + protected JdbcLockManager createJdbcLockManager(boolean useReal) { + return new MySqlLockManagerMock(useReal); + } + + @Test + public void testConcurrentLockDifferentOwners() throws LockException, InterruptedException, ExecutionException, TimeoutException { + + final int participantsNo = 2; + Synchronizer synchronizer = new Synchronizer(participantsNo) { + + private boolean wait = true; + + @Override + public void preAddLockRecord(String resource, String owner) { + if(Owner.A.name().equals(owner)) { + synchronized(this) { + if(wait) { + waitOn(this); + } + } + } + } + + @Override + public void postAddLockRecord(String resource, String owner) { + if(!Owner.A.name().equals(owner)) { + synchronized(this) { + notifyAll(); + wait = false; + } + } + } + + @Override + public void preUpdateLockRecord(String resource, String owner) { + preAddLockRecord(resource, owner); + } + + @Override + public void postUpdateLockRecord(String resource, String owner) { + postAddLockRecord(resource, owner); + } + }; + if(!setSynchronizer(synchronizer)) { + return; + } + ExecutorService executor = Executors.newFixedThreadPool(participantsNo); + // acquireLock by owner A should fail as it will wait for acquireLock by owner B + Future<Boolean> future1 = executor.submit(new Callable<Boolean>() { + @Override + public Boolean call() throws Exception { + try { + lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()); + return false; + } catch(LockException e) { + // this call should fail as Synchronizer delays its lock to make sure the second call locks the resource first + Assert.assertEquals("Cannot lock resource [" + Resource.Resource1.name() + "] for [" + Owner.A.name() + "]: already locked by [" + Owner.B.name() + "]", e.getMessage()); + return true; + } + } + }); + try { + // acquireLock by owner B should success + Future<Boolean> future2 = executor.submit(new Callable<Boolean>() { + @Override + public Boolean call() throws Exception { + // this call should success as Synchronizer delays the above lock to make sure this call success to lock the resource + return lockManager.acquireLock(Resource.Resource1.name(), Owner.B.name()); + } + }); + try { + Assert.assertTrue(future2.get(CONCURRENT_TEST_WAIT_TIME, TimeUnit.SECONDS)); + Assert.assertTrue(future1.get(CONCURRENT_TEST_WAIT_TIME, TimeUnit.SECONDS)); + } finally { + future2.cancel(true); + } + } finally { + future1.cancel(true); + } + } + + @Test + public void testConcurrentLockSameOwner() throws LockException, InterruptedException, ExecutionException, TimeoutException { + final int participantsNo = 2; + Synchronizer synchronizer = new Synchronizer(participantsNo) { + + private boolean wait = true; + + @Override + public void preAddLockRecord(String resource, String owner) { + synchronized(this) { + if(wait) { + wait = false; + waitOn(this); + } + } + } + + @Override + public void postAddLockRecord(String resource, String owner) { + synchronized(this) { + notifyAll(); + } + } + }; + if(!setSynchronizer(synchronizer)) { + return; + } + ExecutorService executor = Executors.newFixedThreadPool(participantsNo); + // one acquireLock should return true and the other should return false + Callable<Boolean> callable = new Callable<Boolean>() { + @Override + public Boolean call() throws Exception { + return lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()); + } + }; + Future<Boolean> future1 = executor.submit(callable); + try { + Future<Boolean> future2 = executor.submit(callable); + try { + boolean future1Res = future1.get(CONCURRENT_TEST_WAIT_TIME, TimeUnit.SECONDS); + boolean future2Res = future2.get(CONCURRENT_TEST_WAIT_TIME, TimeUnit.SECONDS); + // one of the lock requests should return true, the other one false as lock is requested simultaneously from 2 threads by same owner + Assert.assertNotEquals(future1Res, future2Res); + } finally { + future2.cancel(true); + } + } finally { + future1.cancel(true); + } + } + + @Test + public void testConcurrentUnlockSameOwner() throws LockException, InterruptedException, ExecutionException, TimeoutException { + lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()); + final int participantsNo = 2; + Synchronizer synchronizer = new Synchronizer(participantsNo) { + + private boolean wait = true; + + @Override + public void preUpdateLockRecord(String resource, String owner) { + synchronized(this) { + // make sure second call updates the LockRecord first + if(wait) { + wait = false; + waitOn(this); + } + } + } + + @Override + public void postUpdateLockRecord(String resource, String owner) { + synchronized(this) { + notifyAll(); + } + } + }; + if(!setSynchronizer(synchronizer)) { + return; + } + ExecutorService executor = Executors.newFixedThreadPool(participantsNo); + Callable<Boolean> callable = new Callable<Boolean>() { + @Override + public Boolean call() throws Exception { + try { + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + // one of the unlock calls should success + return true; + } catch(LockException e) { + // one of the unlock calls should throw the LockException as the resource should already be unlocked by other call + Assert.assertEquals("Error unlocking resource [" + Resource.Resource1.name() + "]: resource is not locked", e.getMessage()); + return false; + } + } + }; + Future<Boolean> future1 = executor.submit(callable); + try { + Future<Boolean> future2 = executor.submit(callable); + try { + boolean future1Res = future1.get(CONCURRENT_TEST_WAIT_TIME, TimeUnit.SECONDS); + boolean future2Res = future2.get(CONCURRENT_TEST_WAIT_TIME, TimeUnit.SECONDS); + // one of the unlock calls should return true, the other one false as unlock is requested simultaneously from 2 threads by same owner + Assert.assertNotEquals(future1Res, future2Res); + } finally { + future2.cancel(true); + } + } finally { + future1.cancel(true); + } + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/pom.xml b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/pom.xml new file mode 100644 index 000000000..56440c4f0 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/pom.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-dispatcher-common</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <artifactId>lock-manager-lib</artifactId> + <packaging>pom</packaging> + + <modules> + <module>lock-manager-api</module> + <module>lock-manager-impl</module> + <module>lock-manager-features</module> + </modules> +</project>
\ No newline at end of file diff --git a/appc-dispatcher/appc-dispatcher-common/pom.xml b/appc-dispatcher/appc-dispatcher-common/pom.xml new file mode 100644 index 000000000..4054ff79e --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/pom.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dispatcher</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-dispatcher-common</artifactId> + <packaging>pom</packaging> + <name>APPC Dispatcher Common</name> + <description>APPC Dispatcher Common</description> + + <!-- ================================================================================== --> + <!-- The modules we build --> + <!-- ================================================================================== --> + <modules> + <module>appc-data-access-lib</module> + <module>execution-queue-management-lib</module> + <module>state-machine-lib</module> + <module>ranking-framework-lib</module> + <module>lock-manager-lib</module> + <module>domain-model-lib</module> + <module>transaction-recorder</module> + </modules> + +</project>
\ No newline at end of file diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/.gitignore b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/pom.xml b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/pom.xml new file mode 100644 index 000000000..03562065d --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/pom.xml @@ -0,0 +1,37 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dispatcher-common</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-ranking-framework-lib</artifactId> + <packaging>bundle</packaging> + + + <dependencies> + <dependency> + <groupId>com.att.eelf</groupId> + <artifactId>eelf-core</artifactId> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Export-Package>org.openecomp.appc.rankingframework</Export-Package> + <Private-Package>org.openecomp.appc.rankingframework.impl</Private-Package> + <Embed-Dependency>eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Import-Package>!groovy.lang,!javax.jms,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.apache.log,*</Import-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/AbstractRankedAttributesResolverFactory.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/AbstractRankedAttributesResolverFactory.java new file mode 100644 index 000000000..75480b300 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/AbstractRankedAttributesResolverFactory.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.rankingframework; + +import org.openecomp.appc.rankingframework.impl.DefaultRankedAttributesTreeFactory; + +public abstract class AbstractRankedAttributesResolverFactory implements RankedAttributesResolverFactory { + + private static class ReferenceHolder { + private static final RankedAttributesResolverFactory INSTANCE = new DefaultRankedAttributesTreeFactory(); + } + + public static RankedAttributesResolverFactory getInstance() { + return ReferenceHolder.INSTANCE; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/ConfigurationEntry.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/ConfigurationEntry.java new file mode 100644 index 000000000..77fa8930d --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/ConfigurationEntry.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.rankingframework; + +public interface ConfigurationEntry<R> { + Object getAttributeValue(String name); + R getResult(); +} diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/ConfigurationSet.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/ConfigurationSet.java new file mode 100644 index 000000000..2e862d9fc --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/ConfigurationSet.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.rankingframework; + +import java.util.Collection; + +public interface ConfigurationSet<R> { + Collection<String> getRankedAttributeNames(); + + Iterable<ConfigurationEntry<R>> getEntries(); +} diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesContext.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesContext.java new file mode 100644 index 000000000..a8d9b71ec --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesContext.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.rankingframework; + +public interface RankedAttributesContext { + Object getAttributeValue(String name); +} diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesResolver.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesResolver.java new file mode 100644 index 000000000..1948ccc1f --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesResolver.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.rankingframework; + +public interface RankedAttributesResolver<R> { + R resolve(RankedAttributesContext context); +} diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesResolverFactory.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesResolverFactory.java new file mode 100644 index 000000000..7267c046c --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesResolverFactory.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.rankingframework; + +public interface RankedAttributesResolverFactory { + <R> RankedAttributesResolver<R> create(ConfigurationSet<R> config); +} diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/BacktraceStrategy.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/BacktraceStrategy.java new file mode 100644 index 000000000..1365ae834 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/BacktraceStrategy.java @@ -0,0 +1,119 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.rankingframework.impl; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.openecomp.appc.rankingframework.RankedAttributesContext; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +class BacktraceStrategy implements Strategy { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(BacktraceStrategy.class); + + @Override + public <R> R resolve(CompositeNode<R> rootNode, List<String> rankedNames, RankedAttributesContext context) { + + if (logger.isDebugEnabled()) { + StringBuilder buff = new StringBuilder(128); + for (String name : rankedNames) { + buff.append("/{").append(name).append(" = ").append(Utils.value(context.getAttributeValue(name))).append('}'); + } + logger.debug(String.format("Trying to resolve path: %s", buff)); + } + + Set<String> visited = new HashSet<>(); + + CompositeNode<R> parentNode = rootNode; + int depth = 0; + boolean stop = false; + R result = null; + + String attribute = null; + Object value = null; + + do { + if (value == null) { + attribute = rankedNames.get(depth); + value = Utils.value(context.getAttributeValue(attribute)); + } + + Node<R> childNode = parentNode.children().get(value); + + if (childNode != null) { + if (logger.isDebugEnabled()) { + logger.debug(String.format("Found matching node '%s' - checking it out", childNode)); + } + + if (!visited.add(childNode.id())) { + if (logger.isDebugEnabled()) { + logger.debug(String.format("The matching node '%s' was checked before - ignoring it", childNode)); + } + childNode = null; + } + } else { + if (logger.isDebugEnabled()) { + logger.debug(String.format("Node '%s/{%s = %s}' not found - falling back", parentNode, attribute, value != null ? value : "NULL")); + } + } + + if (childNode != null) { + switch (childNode.type()) { + case COMPOSITE: + depth++; + value = null; + parentNode = (CompositeNode<R>) childNode; + break; + case LEAF: + if (logger.isDebugEnabled()) { + logger.debug( String.format("Result node has been resolved succesfully - '%s'", childNode)); + } + result = ((LeafNode<R>) childNode).result(); + stop = true; + break; + default: + throw new IllegalStateException(childNode.type().name()); + } + } else { + if (!value.equals(Constants.DEFAULT_MATCH)) { + logger.debug("Exact match didn't work, trying the default option, if any"); + value = Constants.DEFAULT_MATCH; + } else if (depth > 0) { + if (logger.isDebugEnabled()) { + logger.debug(String.format("Exact match didn't work and no default option available beneath '%s' - moving out", parentNode)); + } + depth--; + value = null; + parentNode = parentNode.parent(); + } else { + logger.debug("Didn't success to resolve the path - stopping without result"); + stop = true; + } + } + } while (!stop); + + return result; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/CompositeNode.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/CompositeNode.java new file mode 100644 index 000000000..0b5e633f3 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/CompositeNode.java @@ -0,0 +1,38 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.rankingframework.impl; + +import java.util.Map; + +class CompositeNode<R> extends NodeBase<R> { + + private final Map<Object, Node<R>> children; + + CompositeNode(String name, Object value, CompositeNode<R> parent, Map<Object, Node<R>> children) { + super(name, value, parent, Type.COMPOSITE); + this.children = children; + } + + Map<Object, Node<R>> children() { + return children; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Constants.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Constants.java new file mode 100644 index 000000000..4111131e2 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Constants.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.rankingframework.impl; + +class Constants { + + private Constants() { + } + + static final String DEFAULT_MATCH = "*"; +} diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/DefaultRankedAttributesTreeFactory.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/DefaultRankedAttributesTreeFactory.java new file mode 100644 index 000000000..d7c48dae6 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/DefaultRankedAttributesTreeFactory.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.rankingframework.impl; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.openecomp.appc.rankingframework.ConfigurationSet; +import org.openecomp.appc.rankingframework.RankedAttributesResolver; +import org.openecomp.appc.rankingframework.RankedAttributesResolverFactory; + +public final class DefaultRankedAttributesTreeFactory implements RankedAttributesResolverFactory { + + private final Strategy DEFAULT_STRATEGY = new BacktraceStrategy(); + + @Override + public <R> RankedAttributesResolver<R> create(ConfigurationSet<R> config) { + + CompositeNode<R> root = RankedAttributesTreeBuilder.build(config); + RankedAttributesResolver<R> tree = new RankedAttributesTree<R>(root, toList(config.getRankedAttributeNames()), + DEFAULT_STRATEGY); + return tree; + } + + private static List<String> toList(Collection<String> col) { + return Collections.unmodifiableList(new ArrayList<>(col)); + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/LeafNode.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/LeafNode.java new file mode 100644 index 000000000..1b1dffdc8 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/LeafNode.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.rankingframework.impl; + +class LeafNode<R> extends NodeBase<R> { + + private final R result; + + LeafNode(String name, Object value, CompositeNode<R> parent, R result) { + super(name, value, parent, Type.LEAF); + this.result = result; + } + + R result() { + return result; + } + + @Override + public String toString() { + StringBuffer buff = new StringBuffer(128); + buff.append(super.toString()); + buff.append(" --> "); + buff.append(result.toString()); + return buff.toString(); + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Node.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Node.java new file mode 100644 index 000000000..c33e4d875 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Node.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.rankingframework.impl; + +interface Node<R> { + enum Type { + LEAF, COMPOSITE + } + + String id(); + + String name(); + + Object value(); + + CompositeNode<R> parent(); + + Type type(); + + boolean isDefaultMatch(); +} diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/NodeBase.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/NodeBase.java new file mode 100644 index 000000000..747d9cfd2 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/NodeBase.java @@ -0,0 +1,87 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.rankingframework.impl; + +import java.util.UUID; + +abstract class NodeBase<R> implements Node<R> { + + private final String name; + private final Object value; + private final Type type; + private final CompositeNode<R> parent; + private final String id = UUID.randomUUID().toString(); + + NodeBase(String name, Object value, CompositeNode<R> parent, Type type) { + this.name = name; + this.value = value; + this.parent = parent; + this.type = type; + } + + @Override + public String id() { + return id; + } + + @Override + public Type type() { + return type; + } + + @Override + public String name() { + return name; + } + + @Override + public Object value() { + return value; + } + + @Override + public CompositeNode<R> parent() { + return parent; + } + + @Override + public boolean isDefaultMatch() { + return value.equals(Constants.DEFAULT_MATCH); + } + + @Override + public String toString() { + if (!name.equals("ROOT")) { + StringBuffer buff = new StringBuffer(128); + if (parent != null) { + buff.append(parent.toString()); + } + buff.append("/{"); + buff.append(name).append(" = ").append(value); + buff.append("}"); + + return buff.toString(); + } else { + return ""; + } + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/RankedAttributesTree.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/RankedAttributesTree.java new file mode 100644 index 000000000..305af85a6 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/RankedAttributesTree.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.rankingframework.impl; + +import java.util.List; + +import org.openecomp.appc.rankingframework.RankedAttributesContext; +import org.openecomp.appc.rankingframework.RankedAttributesResolver; + +class RankedAttributesTree<R> implements RankedAttributesResolver<R> { + + private final CompositeNode<R> root; + private final Strategy strategy; + private final List<String> rankedNames; + + RankedAttributesTree(CompositeNode<R> root, List<String> rankedNames, Strategy strategy) { + this.root = root; + this.rankedNames = rankedNames; + this.strategy = strategy; + } + + @Override + public R resolve(RankedAttributesContext context) { + return strategy.resolve(root, rankedNames, context); + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/RankedAttributesTreeBuilder.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/RankedAttributesTreeBuilder.java new file mode 100644 index 000000000..16aee5607 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/RankedAttributesTreeBuilder.java @@ -0,0 +1,100 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.rankingframework.impl; + +import java.util.HashMap; + +import org.openecomp.appc.rankingframework.ConfigurationEntry; +import org.openecomp.appc.rankingframework.ConfigurationSet; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +class RankedAttributesTreeBuilder { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(RankedAttributesTreeBuilder.class); + + private RankedAttributesTreeBuilder() { + } + + static <R> CompositeNode<R> build(ConfigurationSet<R> config) { + + Object[] names = config.getRankedAttributeNames().toArray(); + + CompositeNode<R> root = new CompositeNode<>("ROOT", Constants.DEFAULT_MATCH, null, + new HashMap<Object, Node<R>>()); + + if (logger.isDebugEnabled()) { + logger.debug(String.format("Building decision tree for ranked attributes: %s", config.getRankedAttributeNames())); + } + + for (ConfigurationEntry<R> entry : config.getEntries()) { + process(entry, names, root); + } + + return root; + } + + private static <R> void process(ConfigurationEntry<R> entry, Object[] names, CompositeNode<R> root) { + CompositeNode<R> parentNode = null; + for (int i = 0; i < names.length; i++) { + + if (i == 0) { + parentNode = root; + } + + final String name = (String) names[i]; + + final Object value = value(entry, name); + + if (i < names.length - 1) { + CompositeNode<R> currentNode = (CompositeNode<R>) parentNode.children().get(value); + if (currentNode == null) { + currentNode = new CompositeNode<>(name, value, parentNode, new HashMap<Object, Node<R>>()); + parentNode.children().put(value, currentNode); + } + parentNode = currentNode; + } else { + LeafNode<R> currentNode = (LeafNode<R>) parentNode.children().get(value); + if (currentNode == null) { + currentNode = new LeafNode<R>(name, value, parentNode, entry.getResult()); + parentNode.children().put(value, currentNode); + + if (logger.isDebugEnabled()) { + logger.debug(String.format("Branch has been created: %s", currentNode)); + } + } else { + logger.error( + String.format("Duplicated configuration entry has been detected for attribute '%s' with value '%s' - the node '%s'exists already", + name, + value, + currentNode)); + throw new IllegalArgumentException("Duplicated configuration entry: " + currentNode); + } + } + } + } + + private static <R> Object value(ConfigurationEntry<R> entry, String name) { + Object value = entry.getAttributeValue(name); + return Utils.value(value); + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Strategy.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Strategy.java new file mode 100644 index 000000000..121f1fb2d --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Strategy.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.rankingframework.impl; + +import java.util.List; + +import org.openecomp.appc.rankingframework.RankedAttributesContext; + +interface Strategy { + <R> R resolve(CompositeNode<R> root, List<String> rankedNames, RankedAttributesContext context); +} diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Utils.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Utils.java new file mode 100644 index 000000000..88ca6d5f5 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Utils.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.rankingframework.impl; + +class Utils { + + private Utils() { + } + + static <R> Object value(Object value) { + if (value == null || (value instanceof String && isEmpty((String) value))) { + value = Constants.DEFAULT_MATCH; + } + + return value; + } + + private static boolean isEmpty(String str) { + return str == null || str.length() == 0; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/java/org/openecomp/appc/rankingframework/TestRankingFramework.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/java/org/openecomp/appc/rankingframework/TestRankingFramework.java new file mode 100644 index 000000000..75301dc37 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/java/org/openecomp/appc/rankingframework/TestRankingFramework.java @@ -0,0 +1,225 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.rankingframework; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; +import org.openecomp.appc.rankingframework.AbstractRankedAttributesResolverFactory; +import org.openecomp.appc.rankingframework.ConfigurationEntry; +import org.openecomp.appc.rankingframework.ConfigurationSet; +import org.openecomp.appc.rankingframework.RankedAttributesContext; +import org.openecomp.appc.rankingframework.RankedAttributesResolver; + +public class TestRankingFramework { + + private static final String COUNTRY = "COUNTRY"; + private static final String STATE = "STATE"; + private static final String CITY = "CITY"; + + private static final List<String> NAMES = Arrays.asList(COUNTRY, STATE, CITY); + + private static final String PACIFIC = "Pacific"; + private static final String ATLANTIC = "Atlantic"; + private static final String ARCTIC = "Arctic"; + private static final String NA = "N/A"; + + private static ConfigurationEntry<String> entry(String [] attributes, String result) { + if (attributes == null || attributes.length != NAMES.size()) { + throw new IllegalArgumentException(); + } + + Map<String, String> map = new HashMap<>(attributes.length); + for (int i = 0; i < attributes.length; i++) { + map.put(NAMES.get(i), attributes[i]); + } + + return new ConfigurationEntryImpl(map, result); + } + + private static ConfigurationSet<String> config(ConfigurationEntry<String> ... entries) { + return new ConfigurationSetImpl(Arrays.asList(entries), NAMES); + } + + private static RankedAttributesContext context(String ... attributes) { + if (attributes == null || attributes.length != NAMES.size()) { + throw new IllegalArgumentException(); + } + + Map<String, String> map = new HashMap<>(attributes.length); + for (int i = 0; i < attributes.length; i++) { + map.put(NAMES.get(i), attributes[i]); + } + + return new Context(map); + } + + private static class ConfigurationSetImpl implements ConfigurationSet<String> { + + private final Collection<ConfigurationEntry<String>> entries; + private final Collection<String> names; + + ConfigurationSetImpl(Collection<ConfigurationEntry<String>> entries, Collection<String> names) { + this.entries = entries; + this.names = names; + } + + @Override + public Iterable<ConfigurationEntry<String>> getEntries() { + return entries; + } + + @Override + public Collection<String> getRankedAttributeNames() { + return names; + } + } + + private static class ConfigurationEntryImpl implements ConfigurationEntry<String> { + + private final Map<String, String> attributes; + private final String result; + + ConfigurationEntryImpl(Map<String, String> attributes, String result) { + this.attributes = attributes; + this.result = result; + } + + @Override + public Object getAttributeValue(String name) { + return attributes.get(name); + } + + @Override + public String getResult() { + return result; + } + } + + private static class Context implements RankedAttributesContext { + + private final Map<String, String> map; + + Context(Map<String, String> map) { + this.map = map; + } + + @Override + public Object getAttributeValue(String name) { + return map.get(name); + } + } + + private static ConfigurationSet<String> testData() { + @SuppressWarnings("unchecked") + ConfigurationSet<String> config = config( + entry(new String [] {"US", "CA", "SFO"}, PACIFIC), + entry(new String [] {"US", "CA", "LA"}, PACIFIC), + entry(new String [] {"US", "FL", "MIAMI"}, ATLANTIC), + entry(new String [] {"US", "AK", "Barrow"}, ARCTIC), + entry(new String [] {"US", "AK", "*"}, PACIFIC), + entry(new String [] {"US", "*", "Houston"}, ATLANTIC), + entry(new String [] {"US", "*", "*"}, NA) + ); + + return config; + } + + private static RankedAttributesResolver<String> resolver(ConfigurationSet<String> config) { + return AbstractRankedAttributesResolverFactory.getInstance().create(config); + } + + @Test + public void testExactMatch() { + + ConfigurationSet<String> config = testData(); + + RankedAttributesResolver<String> resolver = resolver(config) ; + + RankedAttributesContext context = context("US", "CA", "SFO"); + + String result = resolver.resolve(context); + + Assert.assertEquals(PACIFIC, result); + } + + @Test + public void testDefaultMatchPartial() { + + ConfigurationSet<String> config = testData(); + + RankedAttributesResolver<String> resolver = resolver(config) ; + + RankedAttributesContext context = context("US", "AK", "Anchorage"); + + String result = resolver.resolve(context); + + Assert.assertEquals(PACIFIC, result); + } + + @Test + public void testDefaultMatchFull() { + + ConfigurationSet<String> config = testData(); + + RankedAttributesResolver<String> resolver = resolver(config) ; + + RankedAttributesContext context = context("US", "IL", "Chicago"); + + String result = resolver.resolve(context); + + Assert.assertEquals(NA, result); + } + + @Test + public void testDefaultMatchInTheMiddle() { + + ConfigurationSet<String> config = testData(); + + RankedAttributesResolver<String> resolver = resolver(config) ; + + RankedAttributesContext context = context("US", "TX", "Houston"); + + String result = resolver.resolve(context); + + Assert.assertEquals(ATLANTIC, result); + } + + @Test + public void testBacktrace() { + + ConfigurationSet<String> config = testData(); + + RankedAttributesResolver<String> resolver = resolver(config) ; + + RankedAttributesContext context = context("US", "CA", "SJC"); + + String result = resolver.resolve(context); + + Assert.assertEquals(NA, result); + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/resources/com/att/eelf/logback.xml b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/resources/com/att/eelf/logback.xml new file mode 100644 index 000000000..2ac88adbc --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/resources/com/att/eelf/logback.xml @@ -0,0 +1,27 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + 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========================================================= + --> + +<configuration scan="true" scanPeriod="3 seconds" debug="false"> + +<!-- + Dummy file to suppress default EELF configuration + --> +</configuration> diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/resources/logback.xml b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/resources/logback.xml new file mode 100644 index 000000000..c93e4e4a9 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/resources/logback.xml @@ -0,0 +1,46 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + 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========================================================= + --> + +<configuration scan="true" scanPeriod="3 seconds" debug="false"> + + <property name="logDirectory" value="target" /> + + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern> %.-5level %-36.36logger - %msg%n</pattern> + </encoder> + </appender> + + <appender name="FILE" class="ch.qos.logback.core.FileAppender"> + <file>${logDirectory}/debug.log</file> + <encoder> + <pattern> %.-5level %-36.36logger - %msg%n</pattern> + </encoder> + </appender> + + <logger name="org.openecomp.appc" level="DEBUG" additivity="false"> + <appender-ref ref="FILE" /> + </logger> + + <root level="WARN"> + <appender-ref ref="STDOUT" /> + </root> +</configuration> diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/.gitignore b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/pom.xml b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/pom.xml new file mode 100644 index 000000000..10f74c6da --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/pom.xml @@ -0,0 +1,32 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dispatcher-common</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>state-machine-lib</artifactId> + <packaging>bundle</packaging> + + <name>state-machine-lib</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Export-Package>org.openecomp.appc.statemachine.*</Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/StateMachine.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/StateMachine.java new file mode 100644 index 000000000..daa8a1ed3 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/StateMachine.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.statemachine; + +import org.openecomp.appc.statemachine.objects.*; + + +public interface StateMachine { + StateMachineResponse handleEvent(State currentState, Event event) throws InvalidInputException; +} diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/impl/StateMachineFactory.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/impl/StateMachineFactory.java new file mode 100644 index 000000000..d8a135be4 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/impl/StateMachineFactory.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.statemachine.impl; + +import java.util.HashSet; +import java.util.Set; + +import org.openecomp.appc.statemachine.StateMachine; +import org.openecomp.appc.statemachine.objects.Event; +import org.openecomp.appc.statemachine.objects.State; +import org.openecomp.appc.statemachine.objects.StateMachineMetadata; + + +public class StateMachineFactory { + + private StateMachineFactory(){ + + } + + public static StateMachine getStateMachine(StateMachineMetadata metadata){ + StateMachine machine = new StateMachineImpl(metadata); + return machine; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/impl/StateMachineImpl.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/impl/StateMachineImpl.java new file mode 100644 index 000000000..f4f6612f8 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/impl/StateMachineImpl.java @@ -0,0 +1,93 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.statemachine.impl; + +import java.util.HashSet; +import java.util.Set; + +import org.openecomp.appc.statemachine.StateMachine; +import org.openecomp.appc.statemachine.objects.*; + + +public class StateMachineImpl implements StateMachine { + + private final Set<State> states; + + private final Set<Event> events; + + StateMachineImpl(StateMachineMetadata metadata){ + this.states = new HashSet<State>(); + this.states.addAll(metadata.getStates()); + this.events = new HashSet<Event>(); + this.events.addAll(metadata.getEvents()); + } + + public StateMachineResponse handleEvent(State inputState, Event event) throws InvalidInputException{ + + if(!validateInputs(inputState,event)){ + throw new InvalidInputException("VNF State or incoming event is invalid. State = " +inputState + " event = " + event ); + } + + StateMachineResponse response = new StateMachineResponse(); + State currentState = null,nextState = null; + for(State stateInSet:states){ + if(stateInSet.equals(inputState)){ + currentState = stateInSet; + break; + } + } + for(Transition transition : currentState.getTransitions()){ + if(event.equals(transition.getEvent())){ + nextState = transition.getNextState(); + } + } + if(nextState == null){ + response.setResponse(Response.NO_TRANSITION_DEFINED); + } + else if(inputState.equals(nextState)){ + response.setResponse(Response.NO_STATE_CHANGE); + } + else{ + response.setResponse(Response.VALID_TRANSITION); + } + response.setNextState(nextState); + return response; + } + + private boolean validateInputs(State state,Event event){ + if(state ==null || event == null){ + return false; + } + if(!(this.states.contains(state) && this.events.contains(event))){ + return false; + } + return true; + } + + @Override + public String toString() { + return "StateMachineImpl{" + + "states=" + states + + ", events=" + events + + '}'; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Event.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Event.java new file mode 100644 index 000000000..377cd8138 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Event.java @@ -0,0 +1,59 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.statemachine.objects; + +public class Event{ + + private String eventName; + + private Event(){ + + } + @Override + public int hashCode(){ + return this.eventName.hashCode(); + } + @Override + public boolean equals(Object obj){ + if(obj == null){ + return false; + } + if(!(obj instanceof Event)){ + return false; + } + Event event = (Event)obj; + return this.eventName.equals(event.getEventName()); + } + + public Event(String eventName){ + this(); + this.eventName = eventName; + } + + public String getEventName() { + return eventName; + } + @Override + public String toString(){ + return this.eventName; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/InvalidInputException.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/InvalidInputException.java new file mode 100644 index 000000000..db6b6d3ce --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/InvalidInputException.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.statemachine.objects; + +public class InvalidInputException extends Exception{ + public InvalidInputException(String message){ + super(message); + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Response.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Response.java new file mode 100644 index 000000000..8f24c46a0 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Response.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.statemachine.objects; + + +public enum Response { + NO_TRANSITION_DEFINED,NO_STATE_CHANGE,VALID_TRANSITION; + public String toString(){ + return this.name(); + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/State.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/State.java new file mode 100644 index 000000000..18daef02e --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/State.java @@ -0,0 +1,79 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.statemachine.objects; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + + + +public class State{ + private String stateName; + private List<Transition> transitions; + + private State(){ + + } + + public State(String state){ + this(); + this.stateName = state; + this.transitions = new ArrayList<Transition>(); + } + + @Override + public int hashCode(){ + return this.stateName.hashCode(); + } + + @Override + public boolean equals(Object obj){ + if(obj == null){ + return false; + } + if(!(obj instanceof State)){ + return false; + } + State state = (State)obj; + return this.stateName.equals(state.getStateName()); + } + + + public String getStateName(){ + return stateName; + } + + void addTransition(Transition transition){ + this.transitions.add(transition); + } + + public List<Transition> getTransitions() { + return transitions; + } + + @Override + public String toString(){ + return this.stateName; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/StateMachineMetadata.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/StateMachineMetadata.java new file mode 100644 index 000000000..6625fef19 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/StateMachineMetadata.java @@ -0,0 +1,79 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.statemachine.objects; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +public class StateMachineMetadata { + + Set<State> states; + Set<Event> events; + + private StateMachineMetadata(StateMachineMetadataBuilder builder){ + states = builder.states; + events = builder.events; + } + + public Set<State> getStates() { + return states; + } + + public Set<Event> getEvents() { + return events; + } + + public static class StateMachineMetadataBuilder{ + + private Set<State> states; + private Set<Event> events; + + public StateMachineMetadataBuilder(){ + states = new HashSet<State>(); + events = new HashSet<Event>(); + } + + public StateMachineMetadataBuilder addState(State state){ + this.states.add(state); + return this; + } + + public StateMachineMetadataBuilder addEvent(Event event){ + this.events.add(event); + return this; + } + + public StateMachineMetadataBuilder addTransition(State currentState,Event event,State nextState){ + Transition transition = new Transition(event,nextState); + currentState.addTransition(transition); + return this; + } + + public StateMachineMetadata build(){ + StateMachineMetadata machine = new StateMachineMetadata(this); + return machine; + } + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/StateMachineResponse.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/StateMachineResponse.java new file mode 100644 index 000000000..ce75693fc --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/StateMachineResponse.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.statemachine.objects; + + +public class StateMachineResponse { + State nextState; + Response response; + + public StateMachineResponse(){ + + } + + public State getNextState() { + return nextState; + } + + public Response getResponse() { + return response; + } + + public void setNextState(State nextState) { + this.nextState = nextState; + } + + public void setResponse(Response response) { + this.response = response; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Transition.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Transition.java new file mode 100644 index 000000000..4a268f931 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Transition.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.statemachine.objects; + + +public class Transition { + private Event event; + private State nextState; + + private Transition(){ + + } + public Transition(Event event,State nextState){ + this(); + this.event = event; + this.nextState = nextState; + } + + public Event getEvent() { + return event; + } + + public State getNextState() { + return nextState; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/test/java/org/openecomp/appc/statemachine/TestStateMachine.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/test/java/org/openecomp/appc/statemachine/TestStateMachine.java new file mode 100644 index 000000000..735e8e13c --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/test/java/org/openecomp/appc/statemachine/TestStateMachine.java @@ -0,0 +1,98 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.statemachine; + + +import org.junit.Assert; +import org.junit.Test; +import org.openecomp.appc.statemachine.impl.StateMachineFactory; +import org.openecomp.appc.statemachine.objects.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + + +public class TestStateMachine { + + @Test + public void handleEvent() throws InvalidInputException { + +// MetadataReader metadataReader = new MetadataReader(); +// StateMachineMetadata metadata = metadataReader.readMetadata(null); +// +// StateMachine machine = StateMachineFactory.getStateMachine(metadata); +// +// /* +// Testing Positive Scenario passing the valid events and validating the StateMachineResponse +// */ +// for(State state:metadata.getStates()){ +// +// for(Transition transition:state.getTransitions()){ +// Event event = transition.getEvent(); +// State nextState = transition.getNextState(); +// +// StateMachineResponse response = machine.handleEvent(state,event); +// Assert.assertEquals(response.getNextState(),nextState); +// Assert.assertEquals(response.getResponse(),Response.VALID_TRANSITION); +// } +// } +// +// /* +// Testing Negative Scenarios, 1. Passing the valid Events for which Transition is not defined in +// Metadata and validating the StateMachineResponse 2. Passing the invalid events which are not +// registered as events in the StateMachineMetadata and validating StateMachineResponse +// */ +// for(State state:metadata.getStates()){ +// +// for(Transition transition:state.getTransitions()){ +// List<Event> negativeEvents = getNegativeEvents(state,metadata.getEvents()); +// +// for(Event negativeEvent:negativeEvents){ +// StateMachineResponse response = machine.handleEvent(state,negativeEvent); +// Assert.assertEquals(response.getNextState(),null); +// Assert.assertEquals(response.getResponse(),Response.NO_TRANSITION_DEFINED); +// +// boolean flag =false; +// try{ +// response = machine.handleEvent(state,new Event("PUT")); +// } +// catch(InvalidInputException e){ +// flag = true; +// } +// Assert.assertTrue(flag); +// +// } +// } +// } + } + +// private List<Event> getNegativeEvents(State state,Set<Event> events) { +// List<Event> negativeEventList = new ArrayList<>(); +// negativeEventList.addAll(events); +// +// for(Transition transition: state.getTransitions()){ +// negativeEventList.remove(transition.getEvent()); +// } +// return negativeEventList; +// } +} diff --git a/appc-dispatcher/appc-dispatcher-common/transaction-recorder/.gitignore b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/appc-dispatcher/appc-dispatcher-common/transaction-recorder/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/appc-dispatcher/appc-dispatcher-common/transaction-recorder/pom.xml b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/pom.xml new file mode 100644 index 000000000..af399eae2 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/pom.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>appc-dispatcher-common</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>transaction-recorder</artifactId> + <packaging>bundle</packaging> + + <name>transaction-recorder</name> + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-data-access-lib</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic,appc-data-access-lib;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Export-Service>org.openecomp.appc.transactionrecorder.TransactionRecorder</Export-Service> + <Import-Package>!javax.*,!groovy.lang,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.apache.commons.lang3,!org.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package> + <Export-Package>org.openecomp.appc.transactionrecorder,org.openecomp.appc.transactionrecorder.objects</Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + + +</project>
\ No newline at end of file diff --git a/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/TransactionRecorder.java b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/TransactionRecorder.java new file mode 100644 index 000000000..27fdc05b0 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/TransactionRecorder.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.transactionrecorder; + + +import org.openecomp.appc.transactionrecorder.objects.TransactionRecord; + + +public interface TransactionRecorder { + /** + * Stores transaction record to appc database by calling APPC Dao layer. + * @param record Transaction record data. + */ + void store(TransactionRecord record); +} diff --git a/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/impl/TransactionRecorderImpl.java b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/impl/TransactionRecorderImpl.java new file mode 100644 index 000000000..74040d3e4 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/impl/TransactionRecorderImpl.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.transactionrecorder.impl; + +import org.openecomp.appc.dao.util.DBUtils; +import org.openecomp.appc.transactionrecorder.TransactionRecorder; +import org.openecomp.appc.transactionrecorder.objects.TransactionRecord; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + + + +public class TransactionRecorderImpl implements TransactionRecorder { + + private static String APPCCTL_SCHEMA = "appcctl"; + + private static final Logger logger = LoggerFactory.getLogger(TransactionRecorderImpl.class); + + /** + * Stores transaction record to appc database by calling APPC Dao layer. + * @param record Transaction record data. + */ + @Override + public void store(TransactionRecord record) { + Connection connection = null; + PreparedStatement stmt = null; + String queryString = "INSERT INTO transactions VALUES (?,?,?,?,?,?,?,?,?,?)"; + try { + if (logger.isDebugEnabled()) { + logger.debug("Transaction Data started Inserting Successfully into DB"); + } + connection = DBUtils.getConnection(APPCCTL_SCHEMA); + stmt = connection.prepareStatement(queryString); + stmt.setTimestamp(1, new java.sql.Timestamp(record.getTimeStamp().getTime())); + stmt.setString(2, record.getRequestID()); + stmt.setTimestamp(3, new java.sql.Timestamp(record.getStartTime().getTime())); + stmt.setTimestamp(4, new java.sql.Timestamp(record.getEndTime().getTime())); + stmt.setString(5, record.getTargetID()); + stmt.setString(6, record.getTargetType()); + stmt.setString(7, record.getSubComponent()); + stmt.setString(8, record.getOperation()); + stmt.setString(9, record.getResultCode()); + stmt.setString(10, record.getDescription()); + stmt.execute(); + if (logger.isDebugEnabled()) { + logger.debug("Transaction Data Inserted Successfully into DB"); + } + } catch (SQLException e) { + logger.error("Error Accessing Database " + e); + throw new RuntimeException(e); + } finally { + DBUtils.clearResources(null, stmt, connection); + } + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/objects/TransactionRecord.java b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/objects/TransactionRecord.java new file mode 100644 index 000000000..4807aed0a --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/objects/TransactionRecord.java @@ -0,0 +1,147 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * 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.appc.transactionrecorder.objects; + +import java.util.Date; + + +public class TransactionRecord { + + /* +- Timestamp = RequestHandlerInput.RequestHeader.timeStamp +- Request ID = RequestHandlerInput.RequestHeader.requestID +- Start time = from flow +- End time = from flow +- VF_ID = RequestHandlerInput.targetID +- VF_type = genericVnf.getVnfType() +- Sub-component (optional) e.g. VFC_ID/VM UUID - ???? empty +- Operation e.g. Start, Configure etc. = CommandContext.Command +- Result - Success/Error code + description,as published to the initiator RequestHandlerResponse.ACCEPTED/RequestHandlerResponse.REJECTED + String (description) + */ + + private Date timeStamp; + private String requestID; + private Date startTime; + private Date endTime; + private String targetID; + private String targetType; + private String subComponent; + private String operation; + private String resultCode; + private String description; + + public Date getTimeStamp() { + return timeStamp; + } + + public void setTimeStamp(Date timeStamp) { + this.timeStamp = timeStamp; + } + + public String getRequestID() { + return requestID; + } + + public void setRequestID(String requestID) { + this.requestID = requestID; + } + + public Date getStartTime() { + return startTime; + } + + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + + public Date getEndTime() { + return endTime; + } + + public void setEndTime(Date endTime) { + this.endTime = endTime; + } + + public String getTargetID() { + return targetID; + } + + public void setTargetID(String targetID) { + this.targetID = targetID; + } + + public String getTargetType() { + return targetType; + } + + public void setTargetType(String targetType) { + this.targetType = targetType; + } + + public String getSubComponent() { + return subComponent; + } + + public void setSubComponent(String subComponent) { + this.subComponent = subComponent; + } + + public String getOperation() { + return operation; + } + + public void setOperation(String operation) { + this.operation = operation; + } + + public String getResultCode() { + return resultCode; + } + + public void setResultCode(String resultCode) { + this.resultCode = resultCode; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @Override + public String toString() { + return "TransactionRecord{" + + "timeStamp=" + timeStamp + + ", requestID='" + requestID + '\'' + + ", startTime=" + startTime + + ", endTime=" + endTime + + ", targetID='" + targetID + '\'' + + ", targetType='" + targetType + '\'' + + ", subComponent='" + subComponent + '\'' + + ", operation='" + operation + '\'' + + ", resultCode='" + resultCode + '\'' + + ", description='" + description + '\'' + + '}'; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..2d2ef7a23 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + 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========================================================= + --> + +<!-- + Starter Blueprint Camel Definition appc-aai-adapter-blueprint +--> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> + <bean id="transactionRecorderBean" class="org.openecomp.appc.transactionrecorder.impl.TransactionRecorderImpl" scope="singleton" ></bean> + <service id="transactionRecorderService" interface="org.openecomp.appc.transactionrecorder.TransactionRecorder" ref="transactionRecorderBean"/> +</blueprint> |